2014-11-10 1 views
0

Я хочу сделать смещение как: от 0 до 10000 записей, от 10000 до 20000 записей и так далее. Как изменить этот запрос, чтобы добавить смещение? Кроме того, как я могу улучшить этот запрос для производительности?Как сделать смещение в этом запросе SQL Server 2000?

SELECT 
    CASE 
    WHEN c.DataHoraUltimaAtualizacaoILR >= e.DataHoraUltimaAtualizacaoILR AND c.DataHoraUltimaAtualizacaoILR >= t.DataHoraUltimaAtualizacaoILR THEN c.DataHoraUltimaAtualizacaoILR 
    WHEN e.DataHoraUltimaAtualizacaoILR >= c.DataHoraUltimaAtualizacaoILR AND e.DataHoraUltimaAtualizacaoILR >= t.DataHoraUltimaAtualizacaoILR THEN e.DataHoraUltimaAtualizacaoILR 
    WHEN t.DataHoraUltimaAtualizacaoILR >= c.DataHoraUltimaAtualizacaoILR AND t.DataHoraUltimaAtualizacaoILR >= e.DataHoraUltimaAtualizacaoILR THEN t.DataHoraUltimaAtualizacaoILR 
    ELSE c.DataHoraUltimaAtualizacaoILR 
    END AS 'updated_at', 
    p.Email, 
    c.ID_Cliente, 
    p.Nome, 
    p.DataHoraCadastro, 
    p.Sexo, 
    p.EstadoCivil, 
    p.DataNascimento, 
    getdate() as [today], 
    datediff (yy,p.DataNascimento,getdate()) as 'Idade', 
    datepart(month,p.DataNascimento) as 'MesAniversario', 
    e.Bairro, 
    e.Cidade, 
    e.UF, 
    c.CodLoja as codloja_cadastro, 
    t.DDD, 
    t.Numero 
FROM 
    PessoaFisica p 
LEFT JOIN 
    Cliente c ON (c.ID_Pessoa = p.ID_PessoaFisica) 
LEFT JOIN 
    Loja l ON (CAST(l.CodLoja AS integer) = CAST(c.CodLoja AS integer)) 
LEFT JOIN 
    PessoaEndereco pe ON (pe.ID_Pessoa = p.ID_PessoaFisica) 
LEFT JOIN 
    Endereco e ON (e.ID_Endereco = pe.ID_Endereco) 
LEFT JOIN 
    PessoaTelefone pt ON (pt.ID_Pessoa = p.ID_PessoaFisica) 
LEFT JOIN 
    Telefone t ON (t.ID_Telefone = pt.ID_Telefone) 
WHERE 
    p.Email IS NOT NULL 
    AND p.Email <> '' 
    --and p.Email = '[email protected]' 
GROUP BY 
    p.Email, c.ID_Cliente, p.Nome, p.EstadoCivil, p.DataHoraCadastro, 
    c.CodLoja, p.Sexo, e.Bairro, p.DataNascimento, e.Cidade, e.UF, 
    t.DDD, t.Numero, c.DataHoraUltimaAtualizacaoILR, e.DataHoraUltimaAtualizacaoILR, 
    t.DataHoraUltimaAtualizacaoILR 
ORDER BY 
    updated_at DESC 
+0

стандартное правило для индексов: любое поле, используемое в контексте «решения» (например, где, join, group by и т. Д.), Должно иметь индекс на нем. –

+0

Под «смещением» вы подразумеваете, что хотите использовать пейджинг? например «получить первую страницу из 10 000 строк» ​​или «получить вторую страницу из 10 000 строк» ​​и т. д.? – sfuqua

+0

@sfuqua ДА! SQL Server 2000 имеет действительно странный подход к поисковому вызову. Я не знаю, как реализовать это в этом запросе. –

ответ

0

Общий процесс

Если у вас есть доступ к более современной версии SQL Server, то вы можете настроить процесс копирования исходных данных в новую базу данных на ежедневной основе. Первоначально это может быть точная копия исходной базы данных, только для постановки данных. Затем создайте процесс преобразования, используя хранимые процедуры или, возможно, SSIS для высокой производительности. Этот процесс преобразует ваши данные в желаемое конечное состояние и загрузит их в конечную базу данных.

Процесс копирования может быть репликацией, но если ваша промежуточная база данных - это SQL Server 2005 или выше, вы также можете создать простую задачу SSIS для выполнения копии. Запускайте это задание в задаче расписания (SQL Agent) на ежедневной основе. Вы можете объединить данные с двумя нагрузками, а затем преобразовать - но если вы используете SSIS, я рекомендую хранить их в виде отдельных пакетов SSIS, что поможет с проблемами отладки. В запланированной задаче вы можете запускать два пакета обратно друг к другу.


Performance

Вам нужна хорошая индексация на столе, но одна индексация не является достаточным. Кастинг CodLoja как целого не позволит вам использовать индексы в этом поле. Если вам нужно хранить их как строки для какой-то другой причине, то рассмотрите возможность добавления вычисляемых столбцов,

ALTER TABLE xyz Add CodLojaAsInt as (CAST(CodLoja as int)) 

Затем поместите указатель на эту новую вычисляемый столбец. Проблема в том, что любой вызов функции в предложении ON или WHERE заставит SQL Server сканировать все и преобразовать каждую строку, а не входить в индекс.

+0

Проблема в том, что у меня нет этой базы данных, я был нанят, чтобы захватить важные данные из этой базы данных и проанализировать ее на новую базу данных. Я использую Elasticsearch и некоторые другие технологии в новом db. –

+0

Выполняется ли постоянная миграция или постоянное копирование из старой базы данных? Если вы постоянно копируете, я бы сначала сделал массовую загрузку в новую базу данных с помощью промежуточных таблиц, а затем преобразовал данные по мере необходимости. Не уверен, что это помогает. – sfuqua

+0

Это второй вариант, я собираюсь создавать таблицы и переносить данные. Я делаю это постоянно, каждый день. Может ли сформулировать ответ? –

0

После поиска и рассмотрения моей проблемы, @sfuqua помог мне с этим решением. В основном я создам еще несколько организованных таблиц в своей локальной базе данных и получаю все абстрактные/уродливые данные из удаленной БД и обрабатываю их локально в новых таблицах.

Я собираюсь использовать Elasticsearch для ускорения индексирования и запросов.

+0

Если у вас есть момент, можете ли вы вернуться к этому сообщению и пометить мой измененный ответ в качестве ответа? – sfuqua

0

Похоже, вы пытаетесь подражать функции SELECT ... LIMIT X,Y MySQL. SQL Server этого не имеет. В SQL Server 2005+ вы можете использовать ROW_NUMBER() в подзапросе. Однако, поскольку вы находитесь в 2000 году, вам придется сделать это одним из трудных способов.

Они, как я всегда делал это так:

SELECT ... FROM Table WHERE PK IN 
    (SELECT TOP @PageSize PK FROM Table WHERE PK NOT IN 
     (SELECT TOP @StartRow PK FROM Table ORDER BY SortColumn) 
    ORDER BY SortColumn) 
ORDER BY SortColumn 

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

That code and the other solutions are here.