优化 sql 脚本最大化 CPU

Posted

技术标签:

【中文标题】优化 sql 脚本最大化 CPU【英文标题】:Optimize sql script maxing out CPU 【发布时间】:2017-10-16 10:21:07 【问题描述】:

我有一个生成以下 SQL 语句的应用程序。

select ROW_NUMBER() OVER (ORDER BY col1) SerialNo, col1, col2, col3, col4, 
col5, col6, col7, col8
from tableA where  (col3 like '%search1%' or col9 like '%search1%'or col10 
like '%search1%'or col5 like '%search1%' ) 
order by col5

它最近变得如此缓慢(表有超过 600 万条记录)并且它正在耗尽 CPU。关于如何优化此查询的任何想法? “search1”是用户输入的任何字符串,以空格分隔。”

我已使用性能监视器进行分析,并实施了所有似乎使情况恶化的建议。

【问题讨论】:

信息太少。请提供: 1. 表模式(包括索引定义); 2.当前查询的执行计划; 3. 硬件规格 600 万对于运行 LIKE 查询来说是一个很大的数字 您的主要通配符搜索 `LIKE '%...'` 是不可优化的,除非您可以实现类似 sqlperformance.com/2017/09/sql-performance/… 或使用全文搜索。不幸的是,就是这么简单 我创建了非聚集索引,涵盖 where 子句中的所有列以及 where 子句中每个列的单个索引 双端通配符,例如col3 like '%search1%' plus 是那些 & 和 OR 的倍数,没有办法进行简单的“优化” 【参考方案1】:

连接您的列以在此连接上进行搜索;

where col3+col9+col10+col5 like '%search1%'

使用您的过滤器进行子查询,然后在该记录集的行上执行您的 ROW_NUMBER

select ROW_NUMBER() OVER (ORDER BY col1) SerialNo, col1, col2, col3, col4, 
col5, col6, col7, col8
from (select SerialNo,col1, col2, col3, col4, 
col5, col6, col7, col8 from tableA where  col3+col9+col10+col5 like '%search1%'
) as tfiltered
order by col5

【讨论】:

这是个好主意。但是,我不认为是 DBMS 必须执行的四列上的单独 LIKE 导致执行时间长,而是必须读取和比较每条记录的事实。 (加上结果行上的两种排序。)您的查询可能会快一点,也可能会慢一点。我不认为它会带来很大的改变。但是,为什么不试试呢? 感谢您的建议。由于其中一些列可以为空,我还必须在连接之前测试空。记录与原始查询同时返回。【参考方案2】:

会发生这样的事情:

    按顺序读取整个表的记录,以便找到所需的记录。 (这需要更长的时间,DBMS 是否尝试为此使用索引。) 按 col1 对结果行进行排序。当结果集很大时,这可能需要很长时间。 按 col5 对结果行进行排序。这可能又需要很长时间。

我看到以下方法可以加快速度:

    使用多个 CPU,您可以在第一步中强制并行执行。这可能会有所帮助,但如果有多个 CPU 可用,通常 SQL Server 本身会决定在线程中运行它。我在这个主题上找到了这篇文章:https://www.mssqltips.com/sqlservertip/4939/how-to-force-a-parallel-execution-plan-in-sql-server-2016/ 投资硬件。上述点的多个 CPU。更多内存用于排序。更快的驱动器。 限制搜索。到目前为止,用户可以通过输入“thi”来查找“this thing”。如果将其限制为整个单词,则可以使用全文搜索。或者,如果您将其限制为某些关键字,您可以使用自己构建的查找表。 (例如,与其查找 '%shoes%',不如查找与表条目相关的类别,然后查找 category = 'shoes'。)

【讨论】:

很好的建议。我正在查看上面链接中的文章。然而,我当前的执行计划显示了一些关于 Parallelism 的内容。我会做进一步的审查。 至于2,我提出了将CPU核心数从8个增加到16个的要求,看看是否有任何改善,同时增加RAM。您的第三个建议非常棒,正是我正在考虑的。不要让他们在搜索框中输入任何内容,而是强制他们从包含 4 个列的下拉列表中选择一个选项。然而,这是一个需要用户重新定位的重大变化。但它肯定在桌面上。我很感激。

以上是关于优化 sql 脚本最大化 CPU的主要内容,如果未能解决你的问题,请参考以下文章

SQL 优化(分组依据和最大值)

sql server 性能调优之 CPU消耗最大资源分析1 (自sqlserver服务启动以后)

当表很大时找到每个组的最大记录时如何优化sql?

如何防止 CPU “最大化”:同步方法异步调用多个工作人员并使用 SemaphoreSlim 进行节流?

Mysql 优化建议

如何实现php的安全最大化?怎样避免sql注入漏洞和xss跨站脚本攻击漏洞