Как оптимизировать SQL-запрос? - PullRequest
0 голосов
/ 14 июля 2011

У меня есть 2 таблицы («ключи» состоит из около 6 полей, «статистика» состоит из около 65 полей).

Я хочу вставить строки в обе таблицы без дублирования текста фразы. Я использую что-то вроде этого:

UPDATE Keys SET CommandType = 'ADDED', CommandCode = @CommandCode WHERE 
KeyText = @KeyText AND Tab_ID = @TabID AND CommandType = 'DELETED';

INSERT INTO Keys (IsChecked, KeyText, AddDateTime, Tab_ID, KeySource_ID, CommandCode, CommandType)
SELECT 0, @KeyText, datetime(), @TabID, @KeySourceID, @CommandCode, 'ADDED'
WHERE NOT EXISTS (SELECT 1 FROM Keys WHERE Tab_ID = @TabID AND KeyText = @KeyText);

INSERT INTO Statistics (Key_ID)
SELECT ID FROM Keys WHERE KeyText = @KeyText AND Tab_ID = @TabID AND (CommandType IS NULL OR CommandType <> 'DELETED') AND 
NOT EXISTS (SELECT 1 FROM Statistics WHERE Key_ID = (SELECT ID FROM Keys WHERE KeyText = @KeyText AND Tab_ID = @TabID AND (CommandType IS NULL OR CommandType <> 'DELETED') LIMIT 1));

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

Спасибо за помощь и извините за мой плохой английский.

Ответы [ 3 ]

1 голос
/ 15 июля 2011

Создание индексов замедляет запросы вставки и обновления, поскольку индекс должен обновляться вместе с данными.Чтобы оптимизировать ваши конкретные операторы вставки, избавьтесь от любых индексов, которые вам не нужны для типичных операторов выбора.Затем поработайте над упрощением тех положений «и не существует».Это единственный источник какого-либо прироста производительности, который вы собираетесь получить.Попробуйте создать индексы, чтобы ускорить этот подзапрос, как только вы упростили его.

1 голос
/ 15 июля 2011

Вы можете объединить оператор вставки / обновления в один оператор с оператором MERGE.Если вы хотите скопировать изменения ключей в статистику, вы можете использовать оператор OUTPUT.

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

Лучший способ оптимизации - получить приблизительный / фактический план запроса и посмотреть, какие части запроса выполняются медленно.В SQL Server это делается из меню «запрос».В основном, ищите все, что говорит «сканирование», это означает, что вы пропускаете индекс."seek" - это хорошо.

Однако план запросов в основном полезен для тонкой настройки.В этом случае использование другого алгоритма (например, слияния / вывода) будет иметь более радикальное значение.

В SQL Server результаты будут выглядеть примерно так:

INSERT INTO [Statistics] (ID)
SELECT ID FROM
(
    MERGE [Keys] AS TARGET
    USING (
        SELECT @KeyText AS KeyText, @TabID AS TabId, @CommandCode AS CommandCode, @KeySourceID AS KeySourceID, 'Added' AS CommandType
    ) AS SOURCE
    ON (target.KeyText = source.KeyText AND target.Tab_Id = @TabID)
    WHEN MATCHED AND CommandType = 'DELETED' THEN
        UPDATE SET Target.CommandType = Source.CommandType, Target.CommandCode = Source.CommandCode
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (IsChecked, KeyText, AddDateTime, Tab_Id, KeySource_ID, CommandCode, CommandType) VALUES (0, KeyText, getdate(), TabId, KeySourceId, CommandCode, CommandType)
    OUTPUT $Action, INSERTED.ID
) AS Changes (Action, ID)
WHERE Changes.Action = 'INSERT'
AND NOT EXISTS (SELECT 1 FROM Statistics b WHERE b.ID = Changes.ID)
0 голосов
/ 15 июля 2011

Проблема была в плохих показателях для моих таблиц. Я реконструирую его и заменяю некоторые параметры запроса статическим контентом, и он прекрасно работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...