1. 如何解決sql查詢速度太慢
解決方法如下:
1、把數據、日誌、索引放到不同的設備上,增加讀取速度;
2、縱向、橫向分割表,減少表的尺寸;
3、升級硬體;
4、困爛根據查詢條件,建立索引,優化索引、優化悶廳訪問方式,限制結果集的數據量,注意填充因子要適當,索引應該盡量小,使用位元組數小的列建索引螞尺隱好,不要對有限的幾個值的欄位建單一索引如性別欄位;
4、提高網速。
2. 更改SQL Server 2012 資料庫排序規則
針對市面上有部份應用系統或者ERP系統對於資料庫的排序規則是有要求,若安裝資料庫時沒有留意,採用默認安裝後,導致應用打開出現異常或者亂碼現象。其實不用再卸載重裝,通過如下步驟進行更改,節省大量的時間:
1、先停止需要變更 sqlserver 的服務 : 在 運行命令行中 services.msc 命令,在打開的服界面打到並關閉sql server 的服務;(直接通過 Net stop mssqlserver 語句也可以關閉SQL Server 後台服務)
2、執行命令:(cmd命令行)
F:>Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=MSSQLSERVER /SQLSYSADMINACCOUNTS=administrator /SAPWD=****** /SQLCOLLATION=Chinese_PRC_BIN
參數介紹:
InstanceName : MSSQLSERVER 默認為:MSSQLSERVER
SQLSYSADMINACCOUNTS: administrator 默認為:administrator
StrongPassword : sa賬號的密碼
CollationName : Chinese_PRC_BIN (根據實際情況需要填寫)
F:>setup為安裝文件存放路徑;
3、等幾分鍾。出現成功提示
4、執行命令 Net start mssqlserver 啟動 SqlServer
5、原有各個資料庫會被移出,需要手動進行「附加資料庫」資料庫操作
3. 如何解決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 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。
4. sql ORDER BY 多個欄位,排序變慢幾十倍,求解
SQL 中使用order By後,查詢慢,加上主鍵 和 需要排序的欄位組合排序 速度有很大的提升
在SQL Server查詢數據測試,數據約三萬條, 數據欄位以時間倒序排序,
sql:
select ID, column1,column2,column3,record_date from table where ...... order by record_date desc
此時查詢數據需要15秒左中 ,將orderby 修改為 order by ID desc,record_date desc 後,查詢的數據一秒不到即可查詢出來
在linq中,排序的時候,一定要用new 排序的對象,不然ID 將不會被加入到SQL中
linq:
var t = from a in t where ......select a;
t = t.orderby(t=>t.ID).orderby(t=>t.record_date) 此處的ID在解釋成SQL時,不會在SQL中
應寫為:
t = t.orderby(t=>new{t.ID,t.record_date})