SQL語句優化
1 企業SQL優化思路
1、把一個大的不使用索引的SQL語句按照功能進行拆分
2、長的SQL語句無法使用索引,能不能變成2條短的SQL語句讓它分別使用上索引。
3、對SQL語句功能的拆分和修改
4、減少“爛”SQL由運維(DBA)和開發交流(確認),共同確定如何改,最終由DBA執行
5、制定開發流程
2 不適合走索引的場景
1、唯一值少的列上不適合建立索引或者建立索引效率低。例如:性別列
2、小表可以不建立索引,100條記錄。
3、對於數據倉庫,大量全表掃描的情況,建索引反而會慢
3 查看表的唯一值數量
select count(distinct user) from mysql.user; select count(distinct user,host) from mysql.user;
4 建立索引流程
1、找到慢SQL。
show processlist;
記錄慢查詢日志。
2、explain select句,條件列多。
3、查看表的唯一值數量:
select count(distinct user) from mysql.user; select count(distinct user,host) from mysql.user;
條件列多。可以考慮建立聯合索引。
4、建立索引(流量低谷)
force index
5、拆開語句(和開發)。
6、like '%%'不用mysql
7、進行判斷重復的行數
查看行數:
mysql> select count(*) from city; +----------+ | count(*) | +----------+ | 4079 | +----------+ 1 row in set (0.00 sec)
查看去重后的行數:
mysql> select count(distinct countrycode) from city; +-----------------------------+ | count(distinct countrycode) | +-----------------------------+ | 232 | +-----------------------------+ 1 row in set (0.00 sec)
mysql不走索引的原因
1 一些常見的原因
1) 沒有查詢條件,或者查詢條件沒有建立索引
2) 在查詢條件上沒有使用引導列
3) 查詢的數量是大表的大部分,應該是30%以上。
4) 索引本身失效
5) 查詢條件使用函數在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等)
錯誤的例子:select * from test where id-1=9; 正確的例子:select * from test where id=10;
6) 對小表查詢
7) 提示不使用索引
8) 統計數據不真實
9) CBO計算走索引花費過大的情況。其實也包含了上面的情況,這里指的是表占有的block要比索引小。
10)隱式轉換導致索引失效.這一點應當引起重視.也是開發中經常會犯的錯誤.
由於表的字段tel_num定義為varchar2(20),但在查詢時把該字段作為number類型以where條件傳給數據庫,這樣會導致索引失效.
錯誤的例子:select * from test where tel_nume=13333333333;
正確的例子:select * from test where tel_nume='13333333333';
11) 注意使用的特殊符號
1,<> ,!=
2,單獨的>,<,(有時會用到,有時不會)
12)like "%_" 百分號在前.
select * from t1 where name like 'linux培訓%';
13) not in ,not exist.
14) in 盡量改成 union 。
15)當變量采用的是times變量,而表的字段采用的是date變量時.或相反情況。
16)B-tree索引is null不會走,is not null會走,位圖索引 is null,is not null 都會走 。
17)聯合索引 is not null 只要在建立的索引列(不分先后)都會走,
in null時 必須要和建立索引第一列一起使用,當建立索引第一位置條件是is null 時,其他建立索引的列可以是is null(但必須在所有列 都滿足is null的時候),或者=一個值;
當建立索引的第一位置是=一個值時,其他索引列可以是任何情況(包括is null =一個值),以上兩種情況索引都會走。其他情況不會走。
2 需要注意的一些
1) MyISAM 存儲引擎索引鍵長度總和不能超過1000 字節; 2) BLOB 和TEXT 類型的列只能創建前綴索引; 3) MySQL 目前不支持函數索引; 4) 使用不等於(!= 或者<>)的時候MySQL 無法使用索引; 5) 過濾字段使用了函數運算后(如abs(column)),MySQL 無法使用索引; 6) Join 語句中Join 條件字段類型不一致的時候MySQL 無法使用索引; 7) 使用LIKE 操作的時候如果條件以通配符開始( '%abc...')MySQL 無法使用索引; 8) 使用非等值查詢的時候MySQL 無法使用Hash 索引; 9) 在我們使用索引的時候,需要注意上面的這些限制,尤其是要注意無法使用索引的情況,因為這很容易讓我們因為疏忽而造成極大的性能隱患。
數據庫索引的設計原則
為了使索引的使用效率更高,在創建索引時,必須考慮在哪些字段上創建索引和創建什么類型的索引。
1 那么索引設計原則又是怎樣的
1.選擇唯一性索引
唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。
例如,學生表中學號是具有唯一性的字段。為該字段建立唯一性索引可以很快的確定某個學生的信息。如果使用姓名的話,可能存在同名現象,從而降低查詢速度。
2.為經常需要排序、分組和聯合操作的字段建立索引
經常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作會浪費很多時間。
如果為其建立索引,可以有效地避免排序操作。
3.為常作為查詢條件的字段建立索引
如果某個字段經常用來做查詢條件,那么該字段的查詢速度會影響整個表的查詢速度。因此,
為這樣的字段建立索引,可以提高整個表的查詢速度。
4.限制索引的數目
索引的數目不是越多越好。每個索引都需要占用磁盤空間,索引越多,需要的磁盤空間就越大。修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
5.盡量使用數據量少的索引
如果索引的值很長,那么查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文檢索需要的時間肯定要比對CHAR(10)類型的字段需要的時間要多。
6.盡量使用前綴來索引
如果索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。如果只檢索字段的前面的若干個字符,這樣可以提高檢索速度。
7.刪除不再使用或者很少使用的索引
表中的數據被大量更新,或者數據的使用方式被改變后,原有的一些索引可能不再需要。數據庫管理員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。
8.小表不應建立索引
包含大量的列並且不需要搜索非空值的時候可以考慮不建索引