2013-07-09 1 views
1

У меня есть таблица с 2 миллионов записей на данный момент, она будет увеличиваться на 0,05 млн записей в день, так что я хочу оптимизировать этот запросSQL Server - Оптимизировать этот запрос с миллионами записей

Select * from Forex where Id in 
(SELECT MAX(Id) FROM Forex GROUP BY Symbol having Symbol in 
(Select Distinct Symbol from Forex)) 

У меня есть создать некластеризованный индекс поэтому время, затраченное на этот запрос, составляет 673 миллисекунды. Я изменил запрос к

Select * from Forex where Id in 
(SELECT MAX(Id) FROM Forex GROUP BY Symbol having Symbol in 
('AUDCAD','AUDCHF','AUDJPY','AUDNZD','AUDUSD','CADCHF','CHFJPY', 
'EURAUD','EURCAD','EURCHF','EURGBP','EURJPY','EURNOK','EURNZD', 
'EURUSD','GBPCAD','GBPCHF','GBPJPY','GBPUSD','NZDJPY','NZDUSD', 
'USDCAD','USDCHF','USDJPY','USDNOK','USDSEK')) 

Теперь потраченное время 391milliseconds

Можно ли сделать меньше, чем 100milliseconds? Или Некоторые одна помогают оптимизировать этот запрос

+0

Почему не будет: 'Select * от Forex где Id в (SELECT MAX (Id) FROM FOREX GROUP BY Symbol) 'Работа для вас? –

+1

'FROM Forex GROUP BY Symbol with Symbol in (Выбрать отличительный символ от Forex))' кажется бессмысленным. Почему это предложение 'IN' есть? У вас есть отдельная таблица с отдельными символами, которые вы можете использовать? –

+1

Кроме того, какие СУБД вы используете? –

ответ

1

Как только 26 символов и миллион строк 26 индекс стремится может быть лучше (предполагается, что индекс по Symbol ASC, Id DESC)

DECLARE @Id  INT, 
     @Symbol VARCHAR(10) 

DECLARE @Results TABLE(
    Id  INT, 
    Symbol VARCHAR(10)) 

SELECT TOP 1 @Id = Id, 
      @Symbol = Symbol 
FROM Forex 
ORDER BY Symbol ASC, 
      Id DESC 

WHILE @@ROWCOUNT = 1 
    BEGIN 
     INSERT INTO @Results 
     VALUES  (@Id, 
        @Symbol) 

     SELECT TOP 1 @Id = Id, 
        @Symbol = Symbol 
     FROM Forex 
     WHERE Symbol > @Symbol 
     ORDER BY Symbol ASC, 
       Id DESC 
    END 

SELECT * 
FROM @Results 
+0

Это заняло около 7579мс. –

+1

@SatishBejgum - Вы создали индекс на символе ASC, Id DESC? –

+0

Я создал CREATE NONCLUSTERED INDEX [_dta_index_Forex_29_85575343__K2_K1] ВКЛ [dbo].[Форекс] ( \t [Symbol] ASC, \t [Id] ASC ) С (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] GO –

0

Вы должны быть в состоянии избавиться от HAVING пункта:

Select * from Forex where Id in 
(SELECT MAX(Id) FROM Forex GROUP BY Symbol) 

вы также можете попробовать эту версию:

SELECT * FROM Forex F 
WHERE Id = 
(SELECT MAX(Id) FROM Forex WHERE Symbol = F.Symbol) 

, хотя я бы не стал ожидайте, что это будет сильно отличаться.

Некоторые широкие мазки (некоторые из них могут работать, некоторые из них не может):

  1. Убедитесь, что индексы Id и Symbol, Id DESC. Если индекс на Id может быть CLUSTERED, это тоже поможет.
  2. Не возвращайте все столбцы, если вам это не нужно.
  3. De-нормализуют таблицу, перемещая Symbol в другую, меньшую таблицу
  4. Добавить память
  5. Добавить CPU
  6. использовать более жесткие диски
+0

SELECT * FROM Forex F WHERE Id = (SELECT MAX (Id) FROM FOREX WHERE Symbol = F.Symbol) Это заняло 328 миллисекунд –