数据库——索引
1、索引
索引是表的目錄,在查找內容之前可以先在目錄中查找索引位置,以此快速定位查詢數據。對于索引,會保存在額外的文件中。
2、索引種類
- 普通索引:僅加速查詢
- 唯一索引:加速查詢 + 列值唯一(可以有null)
- 主鍵索引:加速查詢 + 列值唯一 + 表中只有一個(不可以有null)
- 組合索引:多列值組成一個索引,
? ? ? ? ? ? ? 專門用于組合搜索,其效率大于索引合并 - 全文索引:對文本的內容進行分詞,進行搜索?
索引合并,使用多個單列索引組合搜索
覆蓋索引,select的數據列只用從索引中就能夠取得,不必讀取數據行,換句話說查詢列要被所建的索引覆蓋
3、相關命令
- 查看表結構desc 表名- 查看生成表的SQLshow create table 表名- 查看索引show index from 表名- 查看執行時間set profiling = 1;SQL...show profiles;4、使用索引和不使用索引
由于索引是專門用于加速搜索而生,所以加上索引之后,查詢效率會快到飛起來。# 有索引mysql> select * from tb1 where name = 'wupeiqi-888';+-----+-------------+---------------------+----------------------------------+---------------------+| nid | name | email | radom | ctime |+-----+-------------+---------------------+----------------------------------+---------------------+| 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |+-----+-------------+---------------------+----------------------------------+---------------------+1 row in set (0.00 sec)# 無索引mysql> select * from tb1 where email = 'wupeiqi888@live.com';+-----+-------------+---------------------+----------------------------------+---------------------+| nid | name | email | radom | ctime |+-----+-------------+---------------------+----------------------------------+---------------------+| 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |+-----+-------------+---------------------+----------------------------------+---------------------+1 row in set (1.23 sec)5、正確使用索引
數據庫表中添加索引后確實會讓查詢速度起飛,但前提必須是正確的使用索引來查詢,如果以錯誤的方式使用,則即使建立索引也會不奏效。
即使建立索引,索引也不會生效:
6、其他注意事項
- 避免使用select *- count(1)或count(列) 代替 count(*)- 創建表時盡量時 char 代替 varchar- 表的字段順序固定長度的字段優先- 組合索引代替多個單列索引(經常使用多個條件查詢時)- 盡量使用短索引- 使用連接(JOIN)來代替子查詢(Sub-Queries)- 連表時注意條件類型需一致- 索引散列值(重復少)不適合建索引,例:性別不適合7、limit分頁
無論是否有索引,limit分頁是一個值得關注的問題
每頁顯示10條: 當前 118 120, 125倒序:大 小980 970 7 6 6 5 54 43 3221 19 98 下一頁:select * from tb1 where nid < (select nid from (select nid from tb1 where nid < 當前頁最小值 order by nid desc limit 每頁數據 *【頁碼-當前頁】) A order by A.nid asc limit 1) order by nid desc limit 10;select * from tb1 where nid < (select nid from (select nid from tb1 where nid < 970 order by nid desc limit 40) A order by A.nid asc limit 1) order by nid desc limit 10;上一頁:select * from tb1 where nid < (select nid from (select nid from tb1 where nid > 當前頁最大值 order by nid asc limit 每頁數據 *【當前頁-頁碼】) A order by A.nid asc limit 1) order by nid desc limit 10;select * from tb1 where nid < (select nid from (select nid from tb1 where nid > 980 order by nid asc limit 20) A order by A.nid desc limit 1) order by nid desc limit 10; View Code8、執行計劃
explain + 查詢SQL - 用于顯示SQL執行信息參數,根據參考信息可以進行SQL優化
mysql> explain select * from tb2; +----+-------------+-------+------+---------------+------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------+ | 1 | SIMPLE | tb2 | ALL | NULL | NULL | NULL | NULL | 2 | NULL | +----+-------------+-------+------+---------------+------+---------+------+------+-------+ 1 row in set (0.00 sec) id查詢順序標識如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 9 | NULL || 2 | DERIVED | tb1 | range | PRIMARY | PRIMARY | 8 | NULL | 9 | Using where |+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+ 特別的:如果使用union連接氣值可能為nullselect_type查詢類型SIMPLE 簡單查詢PRIMARY 最外層查詢SUBQUERY 映射為子查詢DERIVED 子查詢UNION 聯合UNION RESULT 使用聯合的結果...table正在訪問的表名type查詢時的訪問方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/constALL 全表掃描,對于數據表從頭到尾找一遍select * from tb1;特別的:如果有limit限制,則找到之后就不在繼續向下掃描select * from tb1 where email = 'seven@live.com'select * from tb1 where email = 'seven@live.com' limit 1;雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個后就不再繼續掃描。INDEX 全索引掃描,對索引從頭到尾找一遍select nid from tb1;RANGE 對索引列進行范圍查找select * from tb1 where name < 'alex';PS:between andin> >= < <= 操作注意:!= 和 > 符號INDEX_MERGE 合并索引,使用多個單列索引搜索select * from tb1 where name = 'alex' or nid in (11,22,33);REF 根據索引查找一個或多個值select * from tb1 where name = 'seven';EQ_REF 連接時使用primary key 或 unique類型select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;CONST 常量表最多有一個匹配行,因為僅有一行,在這行的列值可被優化器剩余部分認為是常數,const表很快,因為它們只讀取一次。select nid from tb1 where nid = 2 ;SYSTEM 系統表僅有一行(=系統表)。這是const聯接類型的一個特例。select * from (select nid from tb1 where nid = 1) as A;possible_keys可能使用的索引key真實使用的key_lenMySQL中使用索引字節長度rowsmysql估計為了找到所需的行而要讀取的行數 ------ 只是預估值 extra該列包含MySQL解決查詢的詳細信息“Using index”此值表示mysql將使用覆蓋索引,以避免訪問表。不要把覆蓋索引和index訪問類型弄混了?!癠sing where”這意味著mysql服務器將在存儲引擎檢索行后再進行過濾,許多where條件里涉及索引中的列,當(并且如果)它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶where子句的查詢都會顯示“Using where”。有時“Using where”的出現就是一個暗示:查詢可受益于不同的索引?!癠sing temporary”這意味著mysql在對查詢結果排序時會使用一個臨時表。“Using filesort”這意味著mysql會對結果使用一個外部索引排序,而不是按索引次序從表里讀取行。mysql有兩種文件排序算法,這兩種排序方式都可以在內存或者磁盤上完成,explain不會告訴你mysql將使用哪一種文件排序,也不會告訴你排序會在內存里還是磁盤上完成?!癛ange checked for each record(index map: N)”這個意味著沒有好用的索引,新的索引將在聯接的每一行上重新估算,N是顯示在possible_keys列中索引的位圖,并且是冗余的。 詳細 更多參見:
http://www.cnblogs.com/xiaoboluo768/p/5400990.html
http://dev.mysql.com/doc/refman/5.7/en/explain-output.html#jointype_system
9、慢日志查詢
a、配置MySQL自動記錄慢日志
slow_query_log = OFF ? ? ? ? ? ? ? ? ? ? ? ? ? ?是否開啟慢日志記錄
long_query_time = 2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?時間限制,超過此時間,則記錄
slow_query_log_file = /usr/slow.log ? ? ? ?日志文件
log_queries_not_using_indexes = OFF ? ? 為使用索引的搜索是否記錄
注:查看當前配置信息:
? ? show variables like '%query%'
? ? ?修改當前配置:
set global 變量名 = 值
b、查看MySQL慢日志
mysqldumpslow -s at -a ?/usr/local/var/mysql/MacBook-Pro-3-slow.log
""" --verbose 版本 --debug 調試 --help 幫助-v 版本 -d 調試模式 -s ORDER 排序方式what to sort by (al, at, ar, c, l, r, t), 'at' is defaultal: average lock timear: average rows sentat: average query timec: countl: lock timer: rows sentt: query time -r 反轉順序,默認文件倒序拍。reverse the sort order (largest last instead of first) -t NUM 顯示前N條just show the top n queries -a 不要將SQL中數字轉換成N,字符串轉換成S。don't abstract all numbers to N and strings to 'S' -n NUM abstract numbers with at least n digits within names -g PATTERN 正則匹配;grep: only consider stmts that include this string -h HOSTNAME mysql機器名或者IP;hostname of db server for *-slow.log filename (can be wildcard),default is '*', i.e. match all -i NAME name of server instance (if using mysql.server startup script) -l 總時間中不減去鎖定時間;don't subtract lock time from total time """
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/hedeyong/p/8005658.html
總結
- 上一篇: day36 python学习gevent
- 下一篇: 线程同步synchronized理解