如何优化SQL查询

本文关键字:SQL 查询 优化 何优化 | 更新日期: 2023-09-27 18:02:02

我有2个表('keys'由大约6个字段组成,'stats'由大约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));

我如何优化它?我为这个查询字段中使用的所有字段创建索引。也许你能给我推荐一些解决办法?

谢谢你的帮助,很抱歉我的英语不好。

如何优化SQL查询

创建索引会降低插入和更新查询的速度,因为索引必须随着数据一起更新。要优化特定的插入语句,请删除典型选择语句不需要的任何索引。然后努力简化那些"不存在"的从句。这些是您将获得的性能提升的唯一来源。一旦你简化了子查询,试着创建索引来加快子查询的速度。

您可以将插入/更新语句与MERGE语句合并为单个语句。如果要将键的修改复制到统计信息中,可以使用OUTPUT语句。

为了能够评论它们的有效性,您必须将索引添加到问题中,但基本上您希望在包含where子句中所有列的每个表上都有一个索引。您需要为select中不在where子句中的任何内容使用include列。

优化的最佳方法是获得一个估计的/实际的查询计划,并查看查询的哪些部分是慢的。在SQL Server中,这是从"查询"菜单中完成的。基本上,要注意任何写着"scan"的东西,这意味着你缺少了一个索引。"seek"很好

然而,查询计划主要用于微调。在这种情况下,使用不同的算法(如merge/output)将产生更大的差异。

在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)

问题是我的表索引不好。我重建了它,并用静态内容替换了一些查询参数,它工作得很好!