оптимизация запросов на Sql Server 2005 - PullRequest
3 голосов
/ 09 января 2011

у нас есть две связанные таблицы (инвентарь и инвентаризация) на Sql Server 2005. скрипт первой таблицы.

CREATE TABLE [dbo].[inventory](
    [code] [varchar](35) NOT NULL,
    [salePrice1] [decimal](22, 2) NULL,
 CONSTRAINT [PK_inventory] PRIMARY KEY CLUSTERED 
(
    [code] 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 TABLE [dbo].[inventoryLocalization](
    [code] [varchar](35) NOT NULL,
    [language] [varchar](2) NOT NULL,
    [name] [nvarchar](100) NOT NULL,
    [description] [nvarchar](max) NULL,
 CONSTRAINT [PK_inventoryLocalization] PRIMARY KEY CLUSTERED 
(
    [code] ASC,
    [language] ASC,
    [name] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

А у нас запрос зависит от этих двух, следующим образом:

select  i.[code],
        iL.[language], 
        case  
        when iL.[name] is null then (select iL2.name  from dbo.inventoryLocalization iL2 where iL2.[language] = 'de' and iL2.code = i.[code])
        else iL.[name]
        end as [name]
from dbo.inventory i
left join dbo.inventoryLocalization iL on i.code = iL.code and iL.[language] =  'en';

как вы уже догадались, мы выбираем все записи с [language] = 'en', но если для en нет записи, запрос принимает 'de' (по умолчанию). Но этот запрос занимает гораздо больше времени (примерно 13 секунд).

Как вы думаете, какие-либо другие элегантные методы для того же результата позволяют сократить время, которое требуется?

Заранее благодарим за любую помощь, которую вы можете оказать.

Ответы [ 3 ]

4 голосов
/ 09 января 2011

Возможно, медленный, потому что он должен выполнять запрос по требованию, когда оператор case оценивает нуль и запускает подзапрос.

Возможно, это будет быстрее, всегда выполняйте объединение с 'de', а неон делает запрос каждый раз, когда ноль найден.

select  i.[code],
        iL.[language], 
        case  
        when iL.[name] is null then iL2.name
        else iL.[name]
        end as [name]
from dbo.inventory i
left join dbo.inventoryLocalization iL on i.code = iL.code and iL.[language] =  'en'
left join dbo.inventoryLocalization iL2 on i.code = iL2.[code] and iL2.[language] = 'de'
2 голосов
/ 09 января 2011
select i.code
      ,coalesce(en.language, de.language) as language
      ,coalesce(en.name, de.name) as name
  from inventory i
  left join inventoryLocalization en on(i.code = en.code and en.language = 'en')
  left join inventoryLocalization de on(i.code = de.code and de.language = 'de');
0 голосов
/ 09 января 2011

Попробуйте это:

select  i.[code],
        iL.[language], 
        coalesce(il.[name],il2.[name],'Unknown') as [name]
from dbo.inventory i
left join dbo.inventoryLocalization iL on i.code = iL.code and iL.[language] =  'en';
left join  dbo.inventoryLocalization iL2 on i.code=il2.code and il2.[language] = 'de'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...