在SQL Server中使用不區分大小寫的排序規則(在查詢性能方面)有什麼好處/缺點?SQL Server不區分大小寫的排序
我有一個數據庫,目前正在使用不區分大小寫的排序規則,我不太喜歡它。我非常想將其改爲區分大小寫。更改排序規則時應該注意什麼?
在SQL Server中使用不區分大小寫的排序規則(在查詢性能方面)有什麼好處/缺點?SQL Server不區分大小寫的排序
我有一個數據庫,目前正在使用不區分大小寫的排序規則,我不太喜歡它。我非常想將其改爲區分大小寫。更改排序規則時應該注意什麼?
(我說這是一個單獨的答案,因爲它不是我的第一個顯着不同。) 好的,找到一些實際的文檔。這MS KB article說,那裏有是不同排序之間的性能差異,但不是你認爲的地方。所不同的是SQL排序規則之間(向後兼容,但不支持Unicode)和Windows排序(支持Unicode):
一般情況下,在Windows和SQL排序規則之間的性能差異的程度不會重大。僅當工作負載受CPU限制時,纔會出現差異,而不受I/O或網絡速度的限制,並且此CPU的大部分負擔是由字符串操作或在SQL Server中執行的比較造成的。
SQL和Windows排序規則都有區分大小寫和不區分大小寫的版本,所以它聽起來像這不是主要關心的問題。
另一個好故事「從戰壕」于丹的優秀文章,題爲「Collation Hell」:
我繼承了一個混合排序規則環境更加排序規則比我可以指望一方面。不同的排序規則需要解決方法以避免「無法解決排序規則衝突」錯誤,並且這些解決方法會由於非可搜索表達式而導致性能下降。處理混合歸類是一個真正的痛苦,所以我強烈建議你在單個歸類中進行標準化,並且只有在仔細預先考慮後纔會出現偏差。
他總結道:
我個人不認爲性能甚至應該在選擇了適當的歸類加以考慮。我生活在整理地獄中的原因之一是我的前任選擇二進制排序規則來排除我們高度事務性的OLTP系統的每一點性能。除了領先的通配表掃描搜索之外,我發現我們的不同排序規則沒有可衡量的性能差異。性能的關鍵是查詢和索引調整,而不是整理。如果性能對您很重要,那麼我建議您在根據性能預期選擇排序規則之前,先針對實際的應用程序查詢執行性能測試。
希望這會有所幫助。
我想說在生產數據庫中更改爲區分大小寫的排序規則的最大缺點是許多(如果不是大多數)查詢會失敗,因爲它們目前設計爲忽略大小寫。
我還沒有嘗試更改現有數據庫上的排序規則,但我懷疑這樣做可能相當耗時。當過程發生時,您可能必須完全鎖定用戶。除非你已經在dev上進行了徹底的測試,否則不要試試這個。
如果更改數據庫的排序規則,則還必須逐個更改它 - 它們維護創建表時生效的排序規則設置。
create database CollTest COLLATE Latin1_General_CI_AI
go
use CollTest
go
create table T1 (
ID int not null,
Val1 varchar(50) not null
)
go
select name,collation_name from sys.columns where name='Val1'
go
alter database CollTest COLLATE Latin1_General_CS_AS
go
select name,collation_name from sys.columns where name='Val1'
go
結果:
name collation_name
---- --------------
Val1 Latin1_General_CI_AI
name collation_name
---- --------------
Val1 Latin1_General_CI_AI
+1。有趣。我不知道。 – 2010-11-17 14:51:58
+1。這是很好的信息。不知道如果更改了DB排序規則,個別列也需要修改。 – 2010-11-17 14:58:54
如果更改數據庫的整理,但是不是服務器覈對(然後他們不匹配的結果),使用臨時表時要小心。除非在他們的CREATE語句中另有規定,否則他們將使用服務器的默認排序規則,而不是數據庫的規則排序規則,這可能會導致對數據庫列進行JOIN或其他比較(假設他們也更改爲DB的排序規則,如Damien_The_Unbeliever所暗示)失敗。
我找不到任何證實適當構造詢問是否提高工作效率上區分大小寫VS不區分大小寫的數據庫(雖然我懷疑的差異可以忽略不計),但一些事情是清楚的對我說:
喜歡的查詢:
... WHERE UPPER(GivenName) = 'PETER'
不會使用GivenName的索引。你會想這樣的事情:
... WHERE GivenName = 'PETER' COLLATE SQL_Latin1_General_CP1_CS_AS
會更好,它確實。但最大的性能,你不得不做這樣的事情:
... WHERE GivenName = 'PETER' COLLATE SQL_Latin1_General_CP1_CS_AS
AND GivenName LIKE 'PETER'
(見this article的細節)
+1有趣。謝謝(你的)信息。 – 2010-11-17 18:49:50
@BradC:看來你誤讀了這篇文章。它涵蓋了在不區分大小寫的列上進行區分大小寫搜索的更高效方式,而不是像您似乎已經理解的那樣。但是,您確實提出了在區分大小寫的列上嘗試進行不區分大小寫的搜索的可能性的重要問題。我不相信有辦法有效地做到這一點(即沒有掃描)。這個問題明顯強化了你的觀點,即如果沒有特定的業務需求,不區分大小寫的列更好。 – 2011-08-02 15:58:16
@克雷格:哎呀,看起來你是對的。我編輯了我的帖子。 – BradC 2011-08-03 01:13:29
感謝收集這些信息的人。我認爲改變排序規則並不值得我這麼做。 – 2010-11-17 20:14:44