當前位置:首頁 » 編程語言 » sql時慢時快
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql時慢時快

發布時間: 2022-06-07 16:21:58

『壹』 sql執行時間一般不超過多久

你好,一般是10-20毫秒。
擴展:
常見查詢慢的原因常見的話會有如下幾種:
1、沒有索引或沒有用到索引。
PS:索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表

的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜索條件的列上已經創建了索引,MySQL無需掃描任何記錄
即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。
索引類型:
普通索引:這是最基本的索引類型,沒唯一性之類的限制。
唯一性索引:和普通索引基本相同,但所有的索引列只能出現一次,保持唯一性。
主鍵:主鍵是一種唯一索引,但必須指定為"PRIMARY KEY"。
全文索引:MYSQL從3.23.23開始支持全文索引和全文檢索。在MYSQL中,全文索引的索引類型為FULLTEXT。全文索引可以在VARCHAR或者TEXT類型的列上創建。
2、IO吞吐量小形成了瓶頸。
PS:這是從系統層來分析MYSQL是比較耗IO的。一般資料庫監控也是比較關注IO。
監控命令:$iostat -d -k 1 10
參數 -d 表示,顯示設備(磁碟)使用狀態;-k某些使用block為單位的列強制使用Kilobytes為單位;1 10表示,數據顯示每隔1秒刷新一次,共顯示10次。

『貳』 sql server 2008同一個語句查詢,為什麼時快時慢

給你一個網址,裡面有一個案例參考:http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.html

同一個SQL,執行多次時,會重用以前生成的執行計劃。
返回很多記錄跟返回很少記錄,生成的執行計劃是不一樣的,

如果第一次執行時返回的記錄很多,就會造成後面的所有執行,都用慢的執行計劃,
詳細參考上面的文章就知道了

『叄』 SQL緩存問題,第一次查慢,第二次查快

查詢時,資料庫引擎會判斷,如果數據在內存中,則會從內存讀取數據,如果數據不在內存在,則先從硬碟讀到內存,然後再供查詢。
所以第一次查的時候,根據你的語句,資料庫引擎會把一些數據從硬碟讀到內存,第二次再查的時候,就從內存讀數據,就快了很多了。

oracle有一個功能是讓表常駐內存。

『肆』 sql:查詢時快時慢

如果說是sql
server
的話有這種情況,欄位越多,查詢可能越慢,並且如果你的欄位中有比如text,ntext之類的話會有這種情況;
還有,你的這種寫法可能也造成執行慢,SQL在執行時有這樣一個規則,不知道你是否了解,在執行時,SQL
後台會先執行編譯,找到一條最佳查詢路徑,也就是最快的查詢路徑,再真正執行查詢;這個編譯是需要時間的,如果條件復雜,或者由其它的變化而來的條件,會存在編譯的查找最佳路徑的時間問題;
資料庫的欄位越多,會有可能越慢,不管是否是空表,至於什麼原因,好像MICROSOFT沒有說法。
另外1=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 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。

『陸』 同一個SQL,在8個小時內為什麼會有不同的執行計劃有的快,有的慢

一般不是執行計劃不同,除非你有比如建立索引的等操作。
這個慢和快在這里,不是執行計劃決定,而是你的伺服器的情況不同,可能執行時cpu同時處理的所以慢內容很多,所以慢,也可能是內存導致的,也可能是io導致的,也就是說可能性很多,如果要分析那真的要一定時間。
當然,執行計劃也不一定完全一致,比如你會發現第二次查詢一般比第一次快,這是因為上次查詢的內容保存在內存中,只要還沒有被替換掉,那麼下次查詢就會快。這種在執行計劃上是看不出來的,但是確實也存在不同。

『柒』 一個SQL有時執行速度很快有時很慢,請問處理思路

原因有很多的。

  1. 主鍵約束。

    當數據量達到百萬以上的時候,你用主鍵去搜索某一條數據時速度是極快的。但當你不用主鍵去搜索的時候速度就降了幾十倍甚至上百倍,這個是主鍵的好處。

  2. 索引。

    當你的表欄位設置有索引的時候,搜索速度比不創建索引要快幾倍至幾十倍。

  3. sql語句不夠優化。

    在查詢某數據的時候,能不用*就盡量不用,想要哪個欄位就查哪個,多餘的不要,這樣就能達到數據傳輸精簡化,讓查詢速度也能快上許多。

  4. 多表聯合查詢。

    在大數據量的時候這個多表查詢盡量不用,畢竟是很耗內存的,寧願用其他語言循環執行簡單的 select 欄位 from 表名 where 條件 這樣的簡單sql語句,這樣也能加快速度。

其他方面還有很多的,比如伺服器的原因呀,資料庫表結構類型呀。。。我就不多說了。

『捌』 如何解決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 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。