RDBMS:
MySQL mysql
NOSQL:
Redis mongodblinux
centosredis
------------------------------
MySQL 安裝方式:
rpm(yum)
源碼包
通用二進制
---------------------------------
企業中版本選擇
5.6 5.7
選擇 GA 6個月到1年之間的
----------------------------------
MySQL體系結構sql
實例:mongodb
mysqld在啓動時,自動派生master thread ------>生成工做的線程(read write 資源管理 等線程)
預分配內存區域數據庫
mysqld三層結構centos
SQL:緩存
DMLapp
DDL運維
DCL
select * from stu where id=10;
asfdasfdas
鏈接層:
一、提供鏈接協議(TCP/IP socket)
二、驗證的功能
三、提供一個專門的鏈接線程(接收用戶發來的SQL,執行完成以後返回最終結果,可是沒有能力「看懂」SQL,會將SQL語句丟給下一層)
SQL層
一、接收上層發來語句
二、語法檢查模塊進行語法檢查
三、語義的檢查模塊檢查語義,分辨SQL語句的類型,將不一樣種類的語句交給不一樣的解析器。
四、解析器接收到SQL語句,進行解析操做,獲得SQL的執行計劃(explain)
五、優化器負責基於「成本」,找到消耗成本最低的執行計劃。
六、執行器會基於優化器的選擇,執行SQL語句,獲得獲取數據方法,交由下一層繼續處理。
七、將二進制或者16進制數據,結構化成表
八、查詢緩存:SQL語句的hash值+數據結果 ------>redis Tair(memcached)
存儲引擎層
根據上層次獲取數據的方法,把數據提取出來
---------------------------------------------------------------------------
權限管理:
用戶
系統:
定義?
用戶名:密碼
能作什麼?
一、登陸系統
二、管理系統對象
----------------------------------------------
MySQL 邏輯結構
數據庫對象:
庫 :用來存放表對象
建庫-----> 進入庫 ----> 表操做
表 : 原數據+數據行
二維表: 數據行+(列名字+列屬性+多少行+佔多大磁盤空間+權限)原數據
------------------------------
MySQL:
定義?
用戶名@'主機範圍' 主機範圍被稱之爲白名單
主機範圍:
10.0.0.200
oldboy.com (和上面同樣是一個很單一)
10.0.0.% -----》10.0.0.1-10.0.0.254
10.0.0.5% ----- 10.0.0.50-10.0.0.59
% XXXX no
grant all privileges on *.* to app@'10.0.0.%' identified by '123';
開發申請用戶時,提供給管理
app@'10.0.0.%' 密碼: xxxx
權限: ALL privileges
SELECT, INSERT, UPDATE, DELETE, CREATE, RELOAD,
SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER,
SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, DROP
LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT,
CREATE VIEW, SHOW VIEW, CREATE ROUTINE,
ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE
trigger
開發人員可能會用到的權限
create update insert select CREATE VIEW CREATE ROUTINE SHOW VIEW
CREATE TEMPORARY TABLES ALTER
grant 權限 on 權限做用範圍 to 用戶 identified by '密碼'
*.*
py.*
bbs.*
py.t1
grant create,update,insert,select ,CREATE VIEW on bbs.* to bbsuser@'192.168.12.%' identified by '123';
select user,host,password from mysql.user;
開發人員申請用戶流程:
一、IP段
二、用戶名、密碼要求
三、須要哪些權限
---------------------------------
MySQL 邏輯結構
數據庫對象:
庫 :用來存放表對象
建庫-----> 進入庫 ----> 表操做
表 : 原數據+數據行
二維表: 數據行+(列名字+列屬性+多少行+佔多大磁盤空間+權限)原數據
--------------------------------
客戶端工具中自帶命令:
一、\h 或 help 或 ?
二、\G
六、source
source world.sql
七、use
------------------------
show databases;
use world
show tables;
show tables from world;
-------------------
SQL: SQL92 SQL99 標準
DDL
DML
DCL
一、DDL:數據庫對象定義語言
1.1 庫定義
(1)建庫?
CREATE DATABASE db CHARSET utf8;
規範:
庫名小寫。
建庫時加上CHARSET
字符集:utf8 utf8mb4
校對規則:默認都是大小寫不敏感的。
lower_case_table_names=1
(2)刪庫?
DROP DATABASE db;
(3)修改庫
ALTER DATABASE db CHARSET utf8mb4
-------------------------------------
1.2 表定義
Syntax:
CREATE TABLE tbl_name (col_name column_definition,...)
create_definition:
col_name column_definition
| [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
[index_option] ...
| {INDEX|KEY} [index_name] [index_type] (index_col_name,...)
[index_option] ...
| [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
[index_name] [index_type] (index_col_name,...)
[index_option] ...
| {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)
[index_option] ...
| [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name,...) reference_definition
| CHECK (expr)
column_definition:
data_type [NOT NULL | NULL] [DEFAULT default_value]
[AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
[STORAGE {DISK|MEMORY|DEFAULT}]
[reference_definition]
data_type:
---------------------------------------------
| TINYINT[(length)] [UNSIGNED] [ZEROFILL]
| INT[(length)] [UNSIGNED] [ZEROFILL]
| BIGINT[(length)] [UNSIGNED] [ZEROFILL]
| DATETIME[(fsp)]
| CHAR[(length)]
[CHARACTER SET charset_name] [COLLATE collation_name]
| VARCHAR(length)
| ENUM(value1,value2,value3,...)
[CHARACTER SET charset_name] [COLLATE collation_name]
------------------------
table_options:
table_option [[,] table_option] ...
table_option:
| [DEFAULT] CHARACTER SET [=] charset_name
| ENGINE [=] engine_name
---------------
varchar(30)
char(30)
異同?
一、都是能夠存放30個字符長度的數據?
二、varchar會隨着真實的存儲數據長度分配存儲空,須要花費額外資源(cpu、IO)
三、char類型,當即分配指定存儲長度佔用的磁盤空間。不須要花費額外資源(cpu、IO)。
到底怎麼選擇呢?
一、varchar 類型只有在insert 時須要花費額外資源,可是在針對可變長度存儲時,更省空間。
二、char類型,在存儲可變長度數據時,須要用空格填充剩餘空間。
SHOW DATABASES;
業務: 產品的功能 + 用戶的行爲
-- 1.2 表定義
-- 1.2.1 建立表
USE db;
CREATE TABLE t1 (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '學生學號',
NAME VARCHAR(30) NOT NULL COMMENT '學生姓名',
gender ENUM ('m','f') NOT NULL DEFAULT 'm' COMMENT '學生性別',
birthday DATETIME NOT NULL DEFAULT NOW() COMMENT '入學時間'
) ENGINE INNODB CHARSET utf8;
-- 1.2.1 刪除表
DROP TABLE t1;
-- 1.2.3 修改表
-- (1)先添加手機號,內容非空(最後一列)
ALTER TABLE t1 ADD telnum CHAR(11);
-- int -2^31 ~ 2^31-1
-- bigint -2^63 ~ 2^63-1
-- (2)指定添加年齡列到name列後面的位置,示例以下:
ALTER TABLE t1 ADD age TINYINT AFTER NAME;
DESC t1;
-- (3) 經過下面的命令在第一列添加sno字段。p200000001
ALTER TABLE t1 ADD sno CHAR(10) FIRST;
-- (4)若要刪除字段,可採用以下命令。
ALTER TABLE t1 DROP sno;
-- (5)若要同時添加兩個字段,可採用以下命令。
ALTER TABLE t1 ADD sage TINYINT FIRST,ADD qq VARCHAR(15);
-- (6)修改字段類型的命令以下:
ALTER TABLE t1 MODIFY NAME VARCHAR(20) ;
-- (7)修改字段名稱的命令以下:
ALTER TABLE t1 CHANGE age oldboyage CHAR(4) ;
-------------------------------------------------------------
-- DCL:
GRANT
REVOKE
-- DML
INSERT INTO t1(id,NAME,age,...)
UPDATE t1 SET xx=xx WHERE 1=1
DELETE FROM t1 WHERE id=100
-------------防止誤刪除,誤修改-------------
TRIGGER 觸發器 ??? 防止無修改。
-------
僞刪除 —— UPDATE 替代 DELETE
------------------------------------
DESC t1;
CREATE TABLE t2 (id INT ,NAME VARCHAR(20));
DESC t2;
INSERT INTO t2(id,NAME ) VALUES(1,'zhang3'),(2,'li4'),(3,'wang5');
SELECT * FROM t2;
DELETE FROM t2 WHERE id=2;
ALTER TABLE t2 ADD state TINYINT NOT NULL DEFAULT 1;
UPDATE t2 SET state=0 WHERE id =2;
SELECT * FROM t2 WHERE state=1;
使用中間件,作灰度處理。
--------
鏈接
內鏈接:
(1)傳統鏈接
select a.id,b.xyz from a,b
where a.id=b.id
(2)自鏈接
NATURAL JOIN
select a.id,b.xyz from a
NATURAL JOIN b
(3)join using(id)
select a.id,b.xyz from a
JOIN b
using(id);
(4) join on
select a.id,b.xyz from a
JOIN b
on a.id=b.bid
where
(5) left join riht join
select a.id,b.xyz from a
left JOIN b
on a.id=b.bid
------------------------
錶鏈接就是集合操做
內連接
where :
select a.xxx,b.xxx from a,b
where a.xxx=b.xxx and
NATURAL JOIN :
select a.xxx,b.xxx from a
NATURAL JOIN b
join using :
select a.xxx,b.xxx from a
JOIN b
using(id)
join on:
外鏈接
left join
select a.xxx,b.xxx from a
left JOIN b
on a.xx=b.xxx
and age>20
select * from student where id>10
select * from student where id=10 or id=20;
select * from student where id in (10,20);
select * from student where id=10
union all
select * from student where id=20
-----------------------
索引及執行計劃
B樹(默認):
B+tree
B*tree
Hash 索引
fulltext 索引
B樹:
cluster indexes 彙集索引
輔助索引 ------>人爲管控的:unique 普通的 index
--------------------------------------------------------------------------
一、普通索引的管理實戰:
1.1添加索引:
use db
alter table student add index idx_cid(classid);
1.2查詢索引:
show index from student;
desc student;
1.3刪除索引:
alter table student drop key idx_cid;
二、主鍵索引建立
2.1.創建表時
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table t1(id int not null auto_increment primary key);
2.2.創建表後增長
CREATE TABLE `test1` (
`id` int(4) NOT NULL,
`name` char(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
增長自增主鍵
alter table test1 change id id int(11) primary key not null auto_increment;
三、惟一索引
內容惟一,但不是主鍵。
alter table student add unique key uni_tel(telnum);
怎麼判斷某個列的值都是惟一的?
注意:
例子:
一、總行數查詢
select count(*) from world.city;
二、基於某個列去重複以後還剩多少行
select count(distinct population) from world.city;
-------------------
四、前綴索引和聯合索引
4.一、前綴索引:
根據字段的前N個字符創建索引
alter table student add note varchar(200);
alter table student add index idx_note(note(10));
聯合索引:多個字段創建一個索引。
where a女生 and b身高165 and c身材好
index(a,b,c)
特色:前綴生效特性。
alter table people add index idx(a,b,c);
a,ab,abc,ac 能夠走索引或部分走索引。
b bc c ca ba 不走索引。
------------------------
create table people(id int not null auto_increment primary key ,
name varchar(20),gender enum('m','f'),shengao int,tizhong int);
alter table people add index idx_gst(gender,shengao,tizhong);
------------------------------
explain命令的應用
獲取優化器選擇後的執行計劃
mysql> explain select * from city where population <100\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: range
possible_keys: idx_popu
key: idx_popu
key_len: 4
ref: NULL
rows: 1
Extra: Using index condition
1 row in set (0.00 sec)
mysql>
++++++++++++++++++++++++++++
explain select SQL_NO_CACHE * from test where name='oldboy'\G
SQL_NO_CACHE的做用是禁止緩存查詢結果。
explain select name,gender,age from test where gender='F' and age <20;
------
在MySQL中,查詢數據總共兩種方式:全表掃描、索引掃描
經過explain命令的type能夠看到,ALL的話就是全表掃描。
mysql在使用全表掃描時的性能是極其差的,因此MySQL儘可能避免出現全表掃描
全表掃描何時出現?
一、業務確實要獲取全部數據
二、不走索引,致使的全表掃描
2.1 沒索引
2.2 索引建立有問題
2.3 語句有問題
索引掃描有不少種級別,也是經過explain type能看到
------
type : 表示MySQL在表中找到所需行的方式,又稱「訪問類型」
常見類型以下:
index, range, ref, eq_ref, const system, Null
從左到右,性能從最差到最好,咱們認爲至少要達到range級別
一、index:Full Index Scan,index與ALL區別爲index類型只遍歷索引樹
二、range:索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行。
顯而易見的索引範圍掃描是帶有between或者where子句裏帶有<,>查詢。
where條件後 > < >= <= in or between and
咱們在使用索引是,最低應當達到range
use world;
alter table city add index idx_popu(population);
explain select * from city where population >5000000;
explain select * from city where countrycode in ("CHN","JPN");
當mysql使用索引去查找一系列值時,例如IN()和OR列表,也會顯示range(範圍掃描),固然性能上面是有差別的。
explain select * from test where countrycode in ('chn','jpn');
改寫爲:
explain select * from city where countrycode='chn'
union
select * from city where countrycode='jpn';
三、ref:使用非惟一索引掃描或者惟一索引的前綴掃描,返回匹配某個單獨值的記錄行
explain select * from test where countrycode='chn';
四、eq_ref:相似ref,區別就在使用的索引是惟一索引,對於每一個索引鍵值,表中只有一條記錄匹配,簡單來講,
就是多表鏈接中使用primary key或者 unique key做爲關聯條件
A join B
on A.sid=B.sid
五、const、system:當MySQL對查詢某部分進行優化,並轉換爲一個常量時,使用這些類型訪問。
如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量
explain select * from city where id=1000;
六、NULL:MySQL在優化過程當中分解語句,執行時甚至不用訪問表或索引,
例如從一個索引列裏選取最小值能夠經過單獨索引查找完成。
mysql> explain select name,population from city;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4188 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
Extra:
Using temporary
Using filesort
Using join buffer
若是出現以上附加信息:
請檢查order by ,group by ,distinct,join ,union 條件列上沒有索引
explain select * from city where countrycode='CHN' order by population;
額外信息:
key_len 越小越好
rows 越小越好
--------------------------------------
創建索引的原則(運維規範)
select count(distinct user) from mysql.user;
select count(distinct user,host) from mysql.user;
1、數據庫索引的設計原則:
爲了使索引的使用效率更高,在建立索引時,必須考慮在哪些字段上建立索引和建立什麼類型的索引。
那麼索引設計原則又是怎樣的?
1.選擇惟一性索引
惟一性索引的值是惟一的,能夠更快速的經過該索引來肯定某條記錄。
例如,學生表中學號是具備惟一性的字段。爲該字段創建惟一性索引能夠很快的肯定某個學生的信息。
若是使用姓名的話,可能存在同名現象,從而下降查詢速度。
主鍵索引和惟一鍵索引,在查詢中使用是效率最高的。
select count(*) from world.city;
select count(distinct countrycode) from world.city;
select count(distinct countrycode,population ) from world.city;
注意:若是重複值較多,能夠考慮採用聯合索引
2.爲常常須要排序、分組和聯合操做的字段創建索引
常常須要ORDER BY、GROUP BY、DISTINCT和UNION等操做的字段,排序操做會浪費不少時間。
若是爲其創建索引,能夠有效地避免排序操做。
3.爲常做爲查詢條件的字段創建索引
若是某個字段常常用來作查詢條件,那麼該字段的查詢速度會影響整個表的查詢速度。所以,
爲這樣的字段創建索引,能夠提升整個表的查詢速度。
3.1 常常查詢
3.2 列值的重複值少
注:若是常常做爲條件的列,重複值特別多,能夠創建聯合索引。
4.儘可能使用前綴來索引
若是索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索
會很浪費時間。若是隻檢索字段的前面的若干個字符,這樣能夠提升檢索速度。
------------------------以上的是重點關注的,如下是能保證則保證的--------------------
5.限制索引的數目
索引的數目不是越多越好。每一個索引都須要佔用磁盤空間,索引越多,須要的磁盤空間就越大。
修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
6.刪除再也不使用或者不多使用的索引
表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能再也不須要。數據庫管理
員應當按期找出這些索引,將它們刪除,從而減小索引對更新操做的影響。
--------不走索引的狀況(開發規範)
重點關注:
1) 沒有查詢條件,或者查詢條件沒有創建索引
select * from tab; 全表掃描。
select * from tab where 1=1;
(1)select * from tab;
SQL改寫成如下語句:
selec * from tab order by price limit 10 須要在price列上創建索引
(2)
select * from tab where name='zhangsan' name列沒有索引
改:
一、換成有索引的列做爲查詢條件
二、將name列創建索引
2) 查詢結果集是原表中的大部分數據,應該是30%以上。
查詢的結果集,超過了總數行數30%,優化器以爲就沒有必要走索引了。
假如:tab表 id,name id:1-100w ,id列有索引
select * from tab where id>500000;
若是業務容許,可使用limit控制。
怎麼改寫 ?
結合業務判斷,有沒有更好的方式。若是沒有更好的改寫方案
儘可能不要在mysql存放這個數據了。放到redis裏面。
3) 索引自己失效,統計數據不真實
索引有自我維護的能力。
對於表內容變化比較頻繁的狀況下,有可能會出現索引失效。
4) 查詢條件使用函數在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等)
例子:
錯誤的例子:select * from test where id-1=9;
正確的例子:select * from test where id=10;
5)隱式轉換致使索引失效.這一點應當引發重視.也是開發中常常會犯的錯誤.
這樣會致使索引失效. 錯誤的例子:
------------------------
mysql> alter table tab add index inx_tel(telnum);
mysql> desc tab;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| telnum | varchar(20) | YES | MUL | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> select * from tab where telnum='1333333';
+------+------+---------+
| id | name | telnum |
+------+------+---------+
| 1 | a | 1333333 |
+------+------+---------+
1 row in set (0.00 sec)
mysql> select * from tab where telnum=1333333;
+------+------+---------+
| id | name | telnum |
+------+------+---------+
| 1 | a | 1333333 |
+------+------+---------+
1 row in set (0.00 sec)
mysql> explain select * from tab where telnum='1333333';
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
| 1 | SIMPLE | tab | ref | inx_tel | inx_tel | 63 | const | 1 | Using index condition |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)
mysql> explain select * from tab where telnum=1333333;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | tab | ALL | inx_tel | NULL | NULL | NULL | 2 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from tab where telnum=1555555;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | tab | ALL | inx_tel | NULL | NULL | NULL | 2 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from tab where telnum='1555555';
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
| 1 | SIMPLE | tab | ref | inx_tel | inx_tel | 63 | const | 1 | Using index condition |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)
mysql>
---------------------------------------
6)
<> ,not in 不走索引
EXPLAIN SELECT * FROM teltab WHERE telnum <> '110';
EXPLAIN SELECT * FROM teltab WHERE telnum NOT IN ('110','119');
------------
mysql> select * from tab where telnum <> '1555555';
+------+------+---------+
| id | name | telnum |
+------+------+---------+
| 1 | a | 1333333 |
+------+------+---------+
1 row in set (0.00 sec)
mysql> explain select * from tab where telnum <> '1555555';
-----
單獨的>,<,in 有可能走,也有可能不走,和結果集有關,儘可能結合業務添加limit
or或in 儘可能改爲union
EXPLAIN SELECT * FROM teltab WHERE telnum IN ('110','119');
改寫成:
EXPLAIN SELECT * FROM teltab WHERE telnum='110'
UNION ALL
SELECT * FROM teltab WHERE telnum='119'
-----------------------------------
7) like "%_" 百分號在最前面不走
EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '31%' 走range索引掃描
EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '%110' 不走索引
%linux%類的搜索需求,可使用elasticsearch
8) 單獨引用複合索引裏非第一位置的索引列.
列子:
複合索引:
DROP TABLE t1
CREATE TABLE t1 (id INT,NAME VARCHAR(20),age INT ,sex ENUM('m','f'),money INT);
ALTER TABLE t1 ADD INDEX t1_idx(money,age,sex);
DESC t1
SHOW INDEX FROM t1
走索引的狀況測試:EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30 AND sex='m';EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30 ;EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND sex='m'; ----->部分走索引不走索引的:EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=20EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=30 AND sex='m';EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE sex='m';