碰到這樣一個業務場景:每個用戶訂單會有好幾個合同文件,其中某些合同文件需要蓋章,蓋章是有專門的蓋章服務完成的,蓋章完成後,文件會有一個ID與之匹配。 關於這樣一個業務,研發的同學建瞭如下這樣一張表: 往裡面塞數據的時候,需要蓋章的文件: 不需要蓋章的文件: 然後定期抽取需要蓋章的文件送去蓋章服務: ...
碰到這樣一個業務場景:每個用戶訂單會有好幾個合同文件,其中某些合同文件需要蓋章,蓋章是有專門的蓋章服務完成的,蓋章完成後,文件會有一個ID與之匹配。
關於這樣一個業務,研發的同學建瞭如下這樣一張表:
CREATE TABLE [dbo].[UserFile]( [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, .... [NeedStamp] [bit] NULL, [SealApplyId] [int] NULL )
往裡面塞數據的時候,需要蓋章的文件:
INSERT INTO [dbo].[UserFile](...,NeedStamp,SealApplyId)VALUES(...,1,NULL)
不需要蓋章的文件:
INSERT INTO [dbo].[UserFile](...,NeedStamp,SealApplyId)VALUES(...,0,NULL)
然後定期抽取需要蓋章的文件送去蓋章服務:
SELECT * FROM [dbo].[UserFile] WHERE NeedStamp = 1 AND SealApplyId IS NULL
蓋好章之後呢:
UPDATE [dbo].[UserFile] SET SealApplyId = @SealApplyId WHERE ID=@ID
這樣的業務跑一段時間之後發現抽取需要蓋章的數據查詢非常緩慢:
原因是符合NeedStamp = 1需要蓋章的數據非常多,符合SealApplyId IS NULL條件的數據也非常多,雖然符合組合條件NeedStamp = 1 AND SealApplyId IS NULL的數據非常稀少。
這樣即算我以NeedStamp和SealApplyId組合創建索引,查詢都不會用到索引。(無論哪個欄位放在前面統計信息都不會理想)
這樣的情況下我的解決方案有兩種:
1、簡單粗暴的利用hint強制走索引:
SELECT * FROM [dbo].[UserFile] WITH(INDIX(idx_SealApplyId_NeedStamp)) WHERE NeedStamp = 1 AND SealApplyId IS NULL
2、重新定義SealApplyId的初始值(或者分表):
需要蓋章的文件SealApplyId初始值定義為0、不需要蓋章的文件SealApplyId定義為-1(甚至可以直接分表把不需要蓋章的文件放到別的表)。
由於需要蓋章且未蓋章的數據即SealApplyId=0的數據會非常少,這樣直接在SealApplyId上建一個索引即可了。
各位大神有什麼好的其它方案麽?