Почему не срабатывает индекс

relief
Дата: 11.02.2013 16:36:02
Привет.

Есть вот такой запрос

 SELECT     rs.StoreCode,													
				rs.StoreName,
				rs.RetailerCode,														
				rs.RetailerName,
				d.ProductCategory,
				d.ProductLine,
				COUNT(sd.BarCode) as ItemsAmt			
		FROM @stores  rs  
			CROSS JOIN @Models d 
			LEFT JOIN Sales as sd WITH(NOLOCK)
			 ON [sd].[CompanyCode] = @CompanyCode AND [sd].[SaleDate] BETWEEN @StartDate AND @EndDate AND 
			    [sd].[StoreCode]  COLLATE SQL_Latin1_General_CP1_CI_AS = [rs].[StoreCode] AND
				[sd].[ModelId]  COLLATE SQL_Latin1_General_CP1_CI_AS = [d].[ModelId]
		WHERE sd.BarCode IS NOT NULL AND sd.BarCode  <> ''
		 GROUP BY  rs.StoreCode,													
				rs.StoreName,
				rs.RetailerCode,														
				rs.RetailerName,
				d.ProductCategory,
				d.ProductLine


В таблице Sales есть такие индексы
1. CompanyCode, SaleDateб StoreCode, UserId, ModelId
2. BarCode

Вопрос: почему в данном запросе срабытывает индекс 2, а не 1 ?
relief
Дата: 11.02.2013 16:37:20
дополнение.

индекс 1 - первичный ключ
индекс 2 - некластерный индекс, неуникальный
iap
Дата: 11.02.2013 16:43:29
relief,

у Вас фактически не LEFT JOIN, а INNER JOIN - из-за sd.BarCode IS NOT NULL AND sd.BarCode <> ''
Кстати, достаточно sd.BarCode <> ''

Так уберитре же слово LEFT - не обманывайте себя!
AnaceH
Дата: 11.02.2013 16:55:26
relief,

Насколько я помню, для эффективного использования индекса при выборке по диапазону ( в вашем случае [sd].[SaleDate] BETWEEN @StartDate AND @EndDate) поле должно быть последним в индексе. У вас же оно второе.
relief
Дата: 11.02.2013 16:55:27
iap
relief,

у Вас фактически не LEFT JOIN, а INNER JOIN - из-за sd.BarCode IS NOT NULL AND sd.BarCode <> ''
Кстати, достаточно sd.BarCode <> ''

Так уберитре же слово LEFT - не обманывайте себя!


LEFT мне нужен, т.к. надо показывать 0, если нет продаж.

Но даже с учетом изенений так же берется не тот индекс, что я ожидаю

SELECT     rs.StoreCode,													
				rs.StoreName,
				rs.RetailerCode,														
				rs.RetailerName,
				d.ProductCategory,
				d.ProductLine,
				COUNT(sd.BarCode) as ItemsAmt			
		FROM @stores  rs  
			CROSS JOIN @Models d 
			JOIN Sales as sd WITH(NOLOCK)
			 ON [sd].[CompanyCode] = @CompanyCode AND [sd].[SaleDate] BETWEEN @StartDate AND @EndDate AND 
			    [sd].[StoreCode]  COLLATE SQL_Latin1_General_CP1_CI_AS = [rs].[StoreCode] AND
				[sd].[ModelId]  COLLATE SQL_Latin1_General_CP1_CI_AS = [d].[ModelId]
		WHERE sd.BarCode  <> ''
		 GROUP BY  rs.StoreCode,													
				rs.StoreName,
				rs.RetailerCode,														
				rs.RetailerName,
				d.ProductCategory,
				d.ProductLine
Glory
Дата: 11.02.2013 16:58:10
relief
Но даже с учетом изенений так же берется не тот индекс, что я ожидаю

На чем основаны ваши ожидания ?
И какие они собственно ?
relief
Дата: 11.02.2013 17:05:02
Glory
relief
Но даже с учетом изенений так же берется не тот индекс, что я ожидаю

На чем основаны ваши ожидания ?
И какие они собственно ?


Ожидания основаны на основании выполнения "Display Etimated Execution Plan"
Ожидание, что будет браться индекс с первичным ключом (1. CompanyCode, SaleDateб StoreCode, UserId, ModelId)
iap
Дата: 11.02.2013 17:05:49
AnaceH
relief,

Насколько я помню, для эффективного использования индекса при выборке по диапазону ( в вашем случае [sd].[SaleDate] BETWEEN @StartDate AND @EndDate) поле должно быть последним в индексе. У вас же оно второе.
Странное утверждение.
Чтобы использовался индекс по второму полю,
он должен использоваться и для первого,
причём требуется условие точного равенства для первого поля.

relief, если хотите-таки LEFT JOIN, переносите условия из WHERE в ON для LEFT JOINа.
Glory
Дата: 11.02.2013 17:07:17
relief
Ожидания основаны на основании выполнения "Display Etimated Execution Plan"

Так эти ожидания сервера, а не ваши

relief
Ожидание, что будет браться индекс с первичным ключом (1. CompanyCode, SaleDateб StoreCode, UserId, ModelId)

И чем это лучше использования меньшего по размеру индекса ?
relief
Дата: 11.02.2013 17:18:22
Glory
relief
Ожидания основаны на основании выполнения "Display Etimated Execution Plan"

Так эти ожидания сервера, а не ваши

relief
Ожидание, что будет браться индекс с первичным ключом (1. CompanyCode, SaleDateб StoreCode, UserId, ModelId)

И чем это лучше использования меньшего по размеру индекса ?


1. Actual Execution Тоже самое выдал
2. Хотите сказать, что может отработать быстрей по индексу на который я не нацелен? Не задумывался над этим. А простой пример не покажите, или ссылку, когда такое может быть?

Спасибо