Bu, SQL Server 2008 R2 SP2'dir. 2 masam var. İlk tablonun bir VALUE sütunu nvarchar(max)ve ikincisinin de aynı sütunu olması dışında her ikisi de aynıdır (veri ve dizin oluşturma) nvarchar(800). Bu sütun kümelenmemiş bir dizine eklenir. Ayrıca her iki tabloda da kümelenmiş bir dizin oluşturdum. Ayrıca dizinleri yeniden inşa ettim. Bu sütundaki maksimum dize uzunluğu 650'dir.
Ben her iki nvarchar(800)tabloya karşı aynı sorguyu çalıştırırsanız sürekli olarak daha hızlı, iki kat daha hızlı. Tabii "varchar" amacını yeniyor gibi görünüyor. Tablo 800.000+ satır içerir. Sorgu yaklaşık 110.000 satıra (planın tahmin ettiği şey) bakmalıdır.
İo istatistiklerine göre lob okuma yok, bu yüzden her şey arka arkaya görünüyor. İki tablo arasında maliyet yüzdesinde küçük bir fark olması ve tahmini satır boyutunun nvarchar(max)(91 bayt - 63 bayt) daha büyük olması dışında, yürütme planları aynıdır . Okuma sayısı da hemen hemen aynı.
Neden fark var?
===== Şema ======
CREATE TABLE [dbo].[table1](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[ProductID] [bigint] NOT NULL,
[ProductSkeletonID] [bigint] NOT NULL,
[Value] [nvarchar](max) NOT NULL,
[IsKeywordSearchable] [bit] NULL,
[ValueInteger] [bigint] NULL,
[ValueDecimal] [decimal](18, 2) NULL,
[ValueDate] [datetime] NULL,
[TypeOfData] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_table1] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_table1_productskeletonid] ON [dbo].[table1]
(
[ProductSkeletonID] ASC
)
INCLUDE ( [ProductID],
[Value]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE TABLE [dbo].[table2](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[ProductID] [bigint] NOT NULL,
[ProductSkeletonID] [bigint] NOT NULL,
[Value] [nvarchar](800) NOT NULL,
[IsKeywordSearchable] [bit] NULL,
[ValueInteger] [bigint] NULL,
[ValueDecimal] [decimal](18, 2) NULL,
[ValueDate] [datetime] NULL,
[TypeOfData] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_table2] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_table2_productskeletonid] ON [dbo].[table2]
(
[ProductSkeletonID] ASC
)
INCLUDE ( [ProductID],
[Value]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE TABLE [dbo].[table_results](
[SearchID] [bigint] NOT NULL,
[RowNbr] [int] NOT NULL,
[ProductID] [bigint] NOT NULL,
[PermissionList] [varchar](250) NULL,
[SearchWeight] [int] NULL,
CONSTRAINT [PK_table_results] PRIMARY KEY NONCLUSTERED
(
[SearchID] ASC,
[RowNbr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_table_results_SearchID] ON [dbo].[cart_product_searches_results]
(
[SearchID] ASC
)
INCLUDE ( [ProductID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
===== Tablo1 sorgusu ======
SELECT cppev.ProductSkeletonID, cppev.Value, COUNT(*) AS Value FROM table1 cppev
JOIN search_results cpsr ON cppev.ProductID = cpsr.ProductID AND cpsr.SearchID = 227568
WHERE cppev.ProductSkeletonID in (3191, 3160, 3158, 3201)
GROUP BY cppev.ProductSkeletonID, cppev.Value
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'table1'. Scan count 4, logical reads 582, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'table_results'. Scan count 1, logical reads 82, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 1373 ms, elapsed time = 1576 ms.
|--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1008],0)))
|--Stream Aggregate(GROUP BY:([cppev].[Value], [cppev].[ProductSkeletonID]) DEFINE:([Expr1008]=Count(*)))
|--Sort(ORDER BY:([cppev].[Value] ASC, [cppev].[ProductSkeletonID] ASC))
|--Hash Match(Inner Join, HASH:([cpsr].[ProductID])=([cppev].[ProductID]), RESIDUAL:([dbo].[table1].[ProductID] as [cppev].[ProductID]=[dbo].[table_results].[ProductID] as [cpsr].[ProductID]))
|--Index Seek(OBJECT:([dbo].[table_results].[IX_table_results_SearchID] AS [cpsr]), SEEK:([cpsr].[SearchID]=(227568)) ORDERED FORWARD)
|--Index Seek(OBJECT:([dbo].[table1].[IX_table1_productskeletonid] AS [cppev]), SEEK:([cppev].[ProductSkeletonID]=(3158) OR [cppev].[ProductSkeletonID]=(3160) OR [cppev].[ProductSkeletonID]=(3191) OR [cppev].[ProductSkeletonID]=(3201)) ORDERED FORWARD)
===== Table2 sorgusu ======
SELECT cppev.ProductSkeletonID, cppev.Value, COUNT(*) AS Value FROM table2 cppev
JOIN table_results cpsr ON cppev.ProductID = cpsr.ProductID AND cpsr.SearchID = 227568
WHERE cppev.ProductSkeletonID in (3191, 3160, 3158, 3201)
GROUP BY cppev.ProductSkeletonID, cppev.Value
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'table2'. Scan count 4, logical reads 584, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'table_results'. Scan count 1, logical reads 82, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 484 ms, elapsed time = 796 ms.
|--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1008],0)))
|--Stream Aggregate(GROUP BY:([cppev].[Value], [cppev].[ProductSkeletonID]) DEFINE:([Expr1008]=Count(*)))
|--Sort(ORDER BY:([cppev].[Value] ASC, [cppev].[ProductSkeletonID] ASC))
|--Hash Match(Inner Join, HASH:([cpsr].[ProductID])=([cppev].[ProductID]), RESIDUAL:([auctori_core_v40_D].[dbo].[table2].[ProductID] as [cppev].[ProductID]= [dbo].[table2].[ProductID] as [cpsr].[ProductID]))
|--Index Seek(OBJECT:([dbo].[table_results].[IX_table_results_SearchID] AS [cpsr]), SEEK:([cpsr].[SearchID]=(227568)) ORDERED FORWARD)
|--Index Seek(OBJECT:([dbo].[table2].[IX_table2_productskeletonid] AS [cppev]), SEEK:([cppev].[ProductSkeletonID]=(3158) OR [cppev].[ProductSkeletonID]=(3160) OR [cppev].[ProductSkeletonID]=(3191) OR [cppev].[ProductSkeletonID]=(3201)) ORDERED FORWARD)