[英]How can I improve the speed of a SQL query searching for a collection of strings
我有一個名為T_TICKET
的表,該表的T_TICKET
CallId varchar(30)
。
這是我的數據的示例:
CallId | RelatedData
===========================================
MXZ_SQzfGMCPzUA | 0000
MXyQq6wQ7gVhzUA | 0001
MXwZN_d5krgjzUA | 0002
MXw1YXo7JOeRzUA | 0000
...
我正在嘗試查找與CallId
集合匹配的記錄。 像這樣:
SELECT * FROM T_TICKET WHERE CALLID IN(N'MXZInrBl1DCnzUA', N'MXZ0TWkUhHprzUA', N'MXZ_SQzfGMCPzUA', ... ,N'MXyQq6wQ7gVhzUA')
我有200到300個CallId
使用該查詢一次查詢。 該查詢大約需要35秒才能運行。 我可以對表結構,列類型,索引或查詢本身做些什么來提高此查詢的性能?
T_INDEX
當前大約有300,000行。 CallId
不是唯一的。 而且RelatedData
不是唯一的。 我在CallId
上也有一個索引(非聚集)。
我知道SQL的基礎知識,但我不是專業人士。 我想到的一些事情是:
CallId
的類型從varchar
更改為char
。 CallId
的長度(它的長度為30,但實際上,現在,我僅使用15個字節)。 我還沒有嘗試過這些方法,因為它需要更改實時生產數據。 而且,我不確定他們是否會做出重大改進。
這些選擇中的任何一個都會帶來重大改進嗎? 或者,還有其他我可以做的事情來使它更快地執行嗎?
首先,請確保類型相同VARCHAR()
或NVARCHAR()
。 然后,添加一個索引:
create index idx_t_ticket_callid on t_ticket(callid);
如果類型兼容,則SQL Server應使用索引。
您的表就是我們所謂的堆(沒有聚集索引的表) 。 這種表僅適合於數據加載和/或作為臨時表。 我建議您將表轉換為具有集群鍵。 一個好的集群密鑰應該是唯一的,靜態的,狹窄的,不可為空的並且不斷增長的(例如int
/ bigint
身份數據類型)。
堆的另一個缺點是,當您的表上有很多UPDATE
/ DELETE
時,由於轉發記錄,它將減慢SELECT
速度。 Paul Randal引用轉發記錄:
如果轉發記錄出現在堆中,則當記錄定位器指向該位置時,存儲引擎會到達該位置並說,哦,記錄實際上不在這里-它在那兒! 然后,它必須執行另一個(可能是物理的)I / O才能進入具有轉發記錄的頁面。 這可能導致堆效率不及等效的聚集索引。
最后,請確保您在SELECT
上定義了所有列。 避免使用SELECT *
。 我猜您在執行查詢時遇到table scan
。 您可以做的是在索引的SELECT
上INCLUDE
所有列列表,如下所示:
CREATE INDEX [IX_T_TICKET_CallId_INCLUDE] ON [T_TICKET] ([CallId]) INCLUDE ([RelatedData]) WITH (DROP_EXISTING=ON)
事實證明,實際上有一種方法可以在不更改任何數據類型的情況下大大優化我的查詢。
該查詢:
SELECT * FROM T_TICKET
WHERE CALLID IN(N'MXZInrBl1DCnzUA', N'MXZ0TWkUhHprzUA', N'MXZ_SQzfGMCPzUA', ... ,N'MXyQq6wQ7gVhzUA')
正在使用NVARCHAR
類型作為輸入參數(N'MXZInrBl1DCnzUA', N'MXZ0TWkUhHprzUA'...)
。 正如我在問題中指定的那樣, CallId
是VARCHAR
。 Sql Server將表的每一行中的CallId
轉換為NVARCHAR
類型以進行比較,這花費了很長時間(即使我在CallId
上有索引)。
我能夠通過不將參數類型更改為NVARCHAR
來對其進行優化:
SELECT * FROM T_TICKET
WHERE CALLID IN('MXZInrBl1DCnzUA', 'MXZ0TWkUhHprzUA', 'MXZ_SQzfGMCPzUA', ... ,'MXyQq6wQ7gVhzUA')
現在,它不需要花費30秒鍾來運行,而僅需大約.03秒鍾。 感謝所有的投入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.