1. 如何解決sql查詢速度太慢
1. 執行計劃中明明有使用到索引,為什麼執行還是這么慢?
2. 執行計劃中顯示掃描行數為 644,為什麼 slow log 中顯示 100 多萬行?
a. 我們先看執行計劃,選擇的索引 「INDX_BIOM_ELOCK_TASK3(TASK_ID)」。結合 sql 來看,因為有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能會更差,優化器選擇這個索引避免了排序。
那為什麼不選 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很簡單,TASK_DATE 欄位區分度太低了,走這個索引需要掃描的行數很大,而且還要進行額外的排序,優化器綜合判斷代價更大,所以就不選這個索引了。不過如果我們強制選擇這個索引(用 force index 語法),會看到 SQL 執行速度更快少於 10s,那是因為優化器基於代價的原則並不等價於執行速度的快慢;
b. 再看執行計劃中的 type:index,"index" 代表 「全索引掃描」,其實和全表掃描差不多,只是掃描的時候是按照索引次序進行而不是行,主要優點就是避免了排序,但是開銷仍然非常大。
Extra:Using where 也意味著掃描完索引後還需要回表進行篩選。一般來說,得保證 type 至少達到 range 級別,最好能達到 ref。
在第 2 點中提到的「慢日誌記錄Rows_examined: 1161559,看起來是全表掃描」,這里更正為「全索引掃描」,掃描行數確實等於表的行數;
c. 關於執行計劃中:「rows:644」,其實這個只是估算值,並不準確,我們分析慢 SQL 時判斷准確的掃描行數應該以 slow log 中的 Rows_examined 為准。
4. 優化建議:添加組合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
優化過程:
TASK_DATE 欄位存在索引,但是選擇度很低,優化器不會走這個索引,建議後續可以刪除這個索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在這個 sql 中 REL_DEVID 欄位從命名上看選擇度較高,通過下面 sql 來檢驗確實如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由於有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 組合選擇度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在測試環境添加 REL_DEVID,TASK_ID 組合索引,測試 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引後執行計劃:
這里還要注意一點「隱式轉換」:REL_DEVID 欄位數據類型為 varchar,需要在 sql 中加引號:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
執行時間從 10s+ 降到 毫秒級別:
1 row in set (0.00 sec)
結論
一個典型的 order by 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。
2. 一條查詢極為緩慢的sql語句,如何去優化呢
1、將查詢條件欄位簡歷index;
2、將盡可能篩選掉最大數據量的條件放到where條件最後面,因為sql執行時,where條件是由右往左執行。
3、盡可能少用like、in等函數
3. 一條復雜的SQL語句,為什麼第一次查詢很慢,而第二次查詢卻明顯快了
sql語句如果聯合了多張表或頻繁使用多個函數進行查詢,確實會影響效率。需要優化的話,建議給查詢條件設置索引,索引能提高查詢速度;但是如果你的sql語句需要復合查詢而且有很多運算的話,建議還是把一條sql語句拆開成三四條來寫,雖然拆分來寫有點麻煩但是查詢響應速度明顯快好幾倍,不信你試試!
4. SQL查詢太慢,或者根本就查不到數據有超時了
那是因為你沒有建索引的關系,需要在danhao上建立索引,如果danhao是唯一值,需要建唯一索引。
5. c#中 sql查詢為什麼每次第一次查詢會慢。第二次以後都會快
真正的慢不是慢在查詢上,而是慢在資料庫連接上。
而當你第二次查詢的時候,創建的資料庫連接是從連接池裡分配給你的,不需要你重新創建,所以感覺會快很多。
6. 最近我的資料庫(sql)查詢速度很慢,這是什麼原因
查詢慢是和表結構,語句,系統等相關的建索引等方法都可以改善表結構,另外如果返回數據量很大,當然會慢,所以你盡量查詢相對有用的數據再就是查詢語句了比如用in查詢沒有jion查詢快,還有
between
改成
>
<會快再還有,用子查詢也會慢很多,如果是一些很復雜的查詢,可以改用存儲過程會好點,有時用臨時表會慢但,從海量數據中查詢取數進行子查詢又不如用臨時錶快,不同的問題用不同的解決方法,看你要哪種了,單看你的問題無法直接判斷。不過,優化查詢句是關鍵的了。
7. sql語句查詢很慢,如何解決
日期列 有索引嗎?
儲值卡明細 表 的列: 住院號
住院_安排醫生 的 列: 住院號
都有索引嗎?
沒有的話,加上
8. SQL緩存問題,第一次查慢,第二次查快
查詢時,資料庫引擎會判斷,如果數據在內存中,則會從內存讀取數據,如果數據不在內存在,則先從硬碟讀到內存,然後再供查詢。
所以第一次查的時候,根據你的語句,資料庫引擎會把一些數據從硬碟讀到內存,第二次再查的時候,就從內存讀數據,就快了很多了。
oracle有一個功能是讓表常駐內存。
9. Sql參數查詢慢
Declare @t datetime
set @t='2013-08-29'
exec (' select * from table1 where time> ''' + @t + ''' ')
這樣執行 和原來不用參數一樣快
10. sql數據查詢反映很慢
這個問題我也遇見過,慢的話也正常,因為數據比較多
解決辦法啊,首先從表考慮,可以針對這個表建索引,
然後的話說優化查詢語句,可以的話添加 with (nolock);即select * from A with (nolock) 這樣
然後就是where條件了,盡量不要使用like,in這些。盡量添加where條件。
這樣應該可以了,還不行的話,上網查查怎麼優化DB。