內(nèi)容介紹
單表索引失效案例
0、思考題:如果把100萬數(shù)據(jù)插入MYSQL ,如何提高插入效率 (1)關(guān)閉自動(dòng)提交,只手動(dòng)提交一次 (2)刪除除主鍵索引外其他索引 (3)拼寫mysql可以執(zhí)行的長sql,批量插入數(shù)據(jù) (4)使用java多線程 (5)使用框架,設(shè)置屬性,實(shí)現(xiàn)批量插入 1、計(jì)算、函數(shù)導(dǎo)致索引失效 CREATE INDEX idx_name ON emp (NAME); EXPLAIN SELECT * FROM emp WHERE emp.name? LIKE 'abc%'; EXPLAIN SELECT * FROM emp WHERE LEFT(emp.name,3) = 'abc'; ----索引失效 2 LIKE以%開頭索引失效 EXPLAIN SELECT * FROM emp WHERE NAME LIKE '%ab%'; ----索引失效 3、不等于(!= 或者<>)索引失效 EXPLAIN SELECT * FROM emp WHERE emp.name = 'abc' ; EXPLAIN SELECT * FROM emp WHERE emp.name <> 'abc' ; ----索引失效 4、IS NOT NULL 和 IS NULL EXPLAIN SELECT * FROM emp WHERE emp.name IS NULL; EXPLAIN SELECT * FROM emp WHERE emp.name IS NOT NULL; ----索引失效 5、類型轉(zhuǎn)換導(dǎo)致索引失效 EXPLAIN SELECT * FROM emp WHERE NAME='123'; EXPLAIN SELECT * FROM emp WHERE NAME= 123; ----索引失效 6、全值匹配我最愛 EXPLAIN SELECT * FROM emp WHERE emp.age = 30 AND deptid = 4 AND emp.name = 'abcd'; CREATE INDEX idx_age ON emp(age); CREATE INDEX idx_age_deptid ON emp(age,deptid); CREATE INDEX idx_age_deptid_name ON emp(age,deptid,`name`); 7、最佳左前綴法則 EXPLAIN SELECT * FROM emp WHERE emp.age=30 AND emp.name = 'abcd' ; CREATE INDEX idx_age_name ON emp (age,NAME); EXPLAIN SELECT * FROM emp WHERE emp.deptid=1 AND emp.name = 'abcd'; EXPLAIN SELECT * FROM emp WHERE emp.age = 30 AND emp.deptid=1 AND emp.name = 'abcd'; CREATE INDEX idx_age_deptid_name ON emp(age,deptid,`name`); EXPLAIN SELECT * FROM emp WHERE emp.deptid=1 AND emp.name = 'abcd' AND emp.age = 30; 8、索引中范圍條件右邊的列失效 CREATE INDEX idx_age_deptid_name ON emp(age,deptid,`name`); EXPLAIN SELECT * FROM emp WHERE emp.age=30 AND emp.name = 'abc' AND emp.deptId>1000 ; CREATE INDEX idx_age_name_deptid ON emp(age,`name`,deptid); |
關(guān)聯(lián)查詢優(yōu)化
1、數(shù)據(jù)準(zhǔn)備 2、左外連接實(shí)例 (1)明確角色 (2)優(yōu)化 EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card; CREATE INDEX idx_class_card ON class(card); CREATE INDEX idx_book_card ON book(card); *使用LEFT JOIN,前面的是驅(qū)動(dòng)表、后面是被驅(qū)動(dòng)表 針對兩張表的連接條件涉及的列,索引要?jiǎng)?chuàng)建在被驅(qū)動(dòng)表上,驅(qū)動(dòng)表盡量是小表
3、內(nèi)連接實(shí)例 EXPLAIN SELECT * FROM class INNER JOIN book ON class.card = book.card; CREATE INDEX idx_class_card ON class(card); CREATE INDEX idx_book_card ON book(card); *使用INNER JOIN,驅(qū)動(dòng)表、被驅(qū)動(dòng)表不固定,mysql選擇 MySQL優(yōu)化器也會(huì)自動(dòng)選擇驅(qū)動(dòng)表,自動(dòng)選擇驅(qū)動(dòng)表的原則是:索引創(chuàng)建在被驅(qū)動(dòng)表上,驅(qū)動(dòng)表是小表。 4、分析4種查詢sql(mysql5) 5、總結(jié)
|
其他優(yōu)化
1、子查詢優(yōu)化 (1)獲取非掌門人成員 #獲取非掌門人成員 CALL proc_drop_index("atguigudb","emp"); CALL proc_drop_index("atguigudb","dept"); SELECT * FROM t_emp a WHERE a.id NOT IN? (SELECT b.ceo FROM t_dept b WHERE b.ceo IS NOT NULL); EXPLAIN SELECT * FROM emp a WHERE a.id NOT IN? (SELECT b.ceo FROM dept b WHERE b.ceo IS NOT NULL); #子查詢優(yōu)化NOT IN? EXPLAIN SELECT * FROM emp a LEFT JOIN dept b ON a.id = b.ceo WHERE? b.id IS NULL; (2)結(jié)論 盡量不要使用NOT IN 或者 NOT EXISTS,用LEFT JOIN xxx ON xx = xx WHERE xx IS NULL替代 2、排序優(yōu)化 (1)實(shí)例 CALL proc_drop_index("atguigudb","emp"); CALL proc_drop_index("atguigudb","dept"); CREATE INDEX idx_age_deptid_name ON emp (age,deptid,`name`); #無過濾,不索引 EXPLAIN SELECT * FROM emp ORDER BY age,deptid; EXPLAIN SELECT * FROM emp ORDER BY age,deptid LIMIT 10; EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY deptid; #順序錯(cuò),不索引 EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY deptid, `name`; EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY deptid, empno; CREATE INDEX idx_age_deptid_empno ON emp (age,deptid,`empno`); EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY `name`, deptid; EXPLAIN SELECT * FROM emp WHERE deptid=45 ORDER BY age; #方向反,不索引 EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY deptid DESC, `name` DESC; EXPLAIN SELECT * FROM emp WHERE age=45 ORDER BY deptid ASC, `name` DESC;
無過濾,不索引 順序錯(cuò),不索引 方向反,不索引 3、mysql索引選擇 EXPLAIN SELECT * FROM emp WHERE age =30 AND empno <101000 ORDER BY `name`; CREATE INDEX idx_age_empno ON emp (age,`empno`); CREATE INDEX idx_age_name ON emp (age,NAME); *當(dāng)【范圍條件】和【group by 或者 order by】的字段出現(xiàn)二選一時(shí),優(yōu)先觀察條件字段的過濾數(shù)量,如果過濾的數(shù)據(jù)足夠多,而需要排序的數(shù)據(jù)并不多時(shí),優(yōu)先把索引放在范圍字段上。反之,亦然。 也可以將選擇權(quán)交給MySQL:索引同時(shí)存在,mysql自動(dòng)選擇最優(yōu)的方案:(對于這個(gè)例子,mysql選擇idx_age_empno),但是,隨著數(shù)據(jù)量的變化,選擇的索引也會(huì)隨之變化的。 4、雙路排序和單路排序 (1)雙路排序(慢)
(2)單路排序(快) 它的效率更快一些,因?yàn)?/span> 5、分組優(yōu)化
6、覆蓋索引優(yōu)化 總結(jié)
|
慢查詢?nèi)罩?/h6>
1、如何對系統(tǒng)查詢慢做索引優(yōu)化 (1)找運(yùn)維人員開啟生產(chǎn)數(shù)據(jù)庫慢查詢?nèi)罩?/p> (2)等待1-2周時(shí)間,積累慢查詢?nèi)罩?/p> (3)借助工具獲取慢查詢次數(shù)最多和查詢時(shí)間最長的幾個(gè)sql進(jìn)行優(yōu)化 (4)在生產(chǎn)數(shù)據(jù)庫,使用EXPLAIN進(jìn)行sql分析,找到瓶頸,創(chuàng)建索引優(yōu)化 (5)關(guān)閉慢查詢?nèi)罩尽?/p> 2、是什么 一種日志記錄,查看哪些SQL超出了我們的最大忍耐時(shí)間值。 3、使用 (1)開啟slow_query_log SET GLOBAL slow_query_log=1; SHOW VARIABLES LIKE '%slow_query_log%'; (2)修改long_query_time閾值 SHOW VARIABLES LIKE '%long_query_time%'; -- 查看值:默認(rèn)10秒 SET GLOBAL long_query_time=0.1; -- 設(shè)置一個(gè)比較短的時(shí)間,便于測試 (3)運(yùn)行sql (4)查看慢查詢?nèi)罩?/p> (5)使用工具分析慢查詢?nèi)罩?/p> -- 查看mysqldumpslow的幫助信息 mysqldumpslow --help -- 工作常用參考 -- 1.得到返回記錄集最多的10個(gè)SQL mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log -- 2.得到訪問次數(shù)最多的10個(gè)SQL mysqldumpslow -s c -t 10 /var/lib/mysql/atguigu-slow.log -- 3.得到按照時(shí)間排序的前10條里面含有左連接的查詢語句 mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/atguigu-slow.log -- 4.另外建議在使用這些命令時(shí)結(jié)合 | 和more 使用 ,否則語句過多有可能出現(xiàn)爆屏情況 mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more |
1、單表索引失效案例 2、關(guān)聯(lián)查詢優(yōu)化 3、其他優(yōu)化 4、慢查詢?nèi)罩?/p> 5、視圖文章來源:http://www.zghlxwxcb.cn/news/detail-664230.html 6、高性能架構(gòu)模式文章來源地址http://www.zghlxwxcb.cn/news/detail-664230.html |
到了這里,關(guān)于mysql高級三:sql性能優(yōu)化+索引優(yōu)化+慢查詢?nèi)罩镜奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!