在阅读了慢 SQL 查询后,不确定如何优化,这让我想到了查询的总体性能。当然,我们需要第一个表的结果(当其他表被连接时)在连接之前尽可能小(这个问题的内部连接),以使我们的查询更快一点。
例如,应该这样:
SELECT *
FROM ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2
Run Code Online (Sandbox Code Playgroud)
比以下更好/更快:
SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val
Run Code Online (Sandbox Code Playgroud)
我的理论如下(这可能不是正确的实现,我试图从我读过的 SQL Server 2008 内部书籍(MSFT Press)中记住):
因此,如果在上面的语句 #1 中,表较小,则 SQL 引擎在形成笛卡尔积时要做的工作较少。然后,当您到达 where 语句时,您将拥有一个简化的结果集,可从中过滤内存。
我可能离目标太远了,这是不真实的。就像我说的,这是一个理论。
你的意见?
注意:我刚刚想到这个问题,还没有机会自己进行任何测试。
注2:标记为SQL Server的,因为我不知道任何关于MySQL等的实施,请随时接听/评论反正
我注意到一些 DBA 非常频繁地重新启动 SQL Server,有时甚至每晚都重新启动。我相信他们这样做是为了释放一些内存,或者也可能是为了加快查询速度。我知道在重新启动后必须重新编译查询计划,但即使包括这一点,我也想知道这种做法是否有净收益。
每天重新启动 SQL Server 会使其运行得更快吗?
什么是 Percona?
它与 MySQL 有何不同?
我们什么时候应该考虑从库存 MySQL 切换(或升级)到 Percona?
为了在我们的情况下添加一些细节,我们几乎只使用具有广泛外键约束和一些存储过程的 InnoDB(我知道 Percona 已经做了很多优化)。
我们目前发现 MySQL 对我们的查询优化不佳,因此任何超过 3-4 个连接的查询我们都必须使用 STRAIGHT 连接显式构建以提高性能。
我们在 SQL 2005 上有一个生产数据库服务器。一切正常运行了一段时间,但几周后我们看到性能显着下降。只有重新启动 SQL Server 才能使性能恢复正常。
一些背景:
我们在非高峰时间尝试了几件事: - 运行 DBCC DROPCLEANBUFFERS(带有 CHECKPOINT)以清除数据缓存。它没有任何效果,也不会清除任何 RAM 使用量)。- 运行 FREEPROCCACHE 和 FREESYSTEMCACHE 以清除查询计划和存储的 proc 缓存。没有效果。
显然,在活跃的生产环境中重新启动 SQL Server 并不理想。我们缺少一些东西。还有其他人经历过这个吗?
更新:2012 年 4 月 28 日 仍在与这个问题作斗争。我已将 SQL Server 的内存降低到 10 GB,只是为了排除与操作系统的任何争用。我越来越接近缩小范围,但下一步需要一些帮助。
这是我发现的,重新启动 SQL Server 后,页面文件在 12.3 GB 和 12.5 GB 之间徘徊。它会保持这种状态好几天。服务器线程总数将在 850 到 930 之间挂起 - 在几天内也保持稳定和一致(sqlserver 稳定在 55 到 85 之间,具体取决于流量)。
然后,有一个“事件”。我不知道事件是什么,我在日志中看不到它,也看不到在星期几或它发生的时间有任何一致的东西,但是他的页面文件突然跳到了 14.1 或 14.2 …
我需要一个可以在(或作为)函数中使用并检索 n 值的所有组合的查询。我需要长度 k 的所有组合,其中 k = 1..n。
扩展样本输入和结果,因此输入有 3 个值而不是 2 - 但是,输入值的数量可能从 1 到 n 不等。
示例:输入:在多行中的一列中包含值的表
Value (nvarchar(500))
------
Ann
John
Mark
Run Code Online (Sandbox Code Playgroud)
输出#1:在一列中连接值的表
Ann
John
Mark
Ann,John
John,Mark
Ann,Mark
Ann,John,Mark
Run Code Online (Sandbox Code Playgroud) 这个问题与我的旧问题有关。执行以下查询需要 10 到 15 秒:
SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE (Charindex('123456789',CAST([company].dbo.[customer].[Phone no] AS VARCHAR(MAX)))>0)
Run Code Online (Sandbox Code Playgroud)
在一些文章中,我看到使用CAST并且CHARINDEX不会从索引中受益。还有一些文章说 usingLIKE '%abc%'不会从索引中受益,而LIKE 'abc%'会:
http://bytes.com/topic/sql-server/answers/81467-using-charindex-vs-like-where /sf/ask/56264841/ -like-queries http://www.sqlservercentral.com/Forums/Topic186262-8-1.aspx#bm186568
在我的情况下,我可以将查询重写为:
SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE [company].dbo.[customer].[Phone no] LIKE '%123456789%'
Run Code Online (Sandbox Code Playgroud)
此查询提供与前一个相同的输出。我为 column 创建了一个非聚集索引Phone no。当我执行此查询时,它仅在1 秒内运行。与之前的14 秒相比,这是一个巨大的变化。
如何LIKE '%123456789%'从索引中受益?
为什么列出的文章声明它不会提高性能?
我尝试重写查询以使用CHARINDEX,但性能仍然很慢。为什么不像查询那样CHARINDEX从索引中受益LIKE?
查询使用CHARINDEX:
SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [Company].dbo.[customer]
WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 …Run Code Online (Sandbox Code Playgroud) 我正在努力通过警告Operator usedtempdb最大限度地减少查询计划的排序操作成本to spill data during execution with spill level 2
我在溢出级别 1 的执行期间发现了几篇与溢出数据相关的帖子,但不是级别 2。级别 1 似乎是由过时的统计数据引起的,那么级别 2 呢?我找不到任何与level 2.
我发现这篇与排序警告相关的文章非常有趣:
我的 SQL 服务器?
Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) 2016 年 6 月 17 日 19:14:09 版权所有 (c) Microsoft Corporation Enterprise Edition(64 位),Windows NT 6.3(内部版本 9600:)(管理程序)
我的硬件?
运行以下查询以查找硬件:
-- 来自 SQL Server 2012 的硬件信息
SELECT cpu_count AS [Logical CPU Count], hyperthread_ratio AS …Run Code Online (Sandbox Code Playgroud) performance sql-server memory execution-plan sort-operator query-performance
我们正在对 CPU 利用率高的服务器进行故障排除。在发现查询并没有真正导致它之后,我们开始研究编译。
性能监视器显示少于 50 次编译/秒和少于 15 次重新编译/秒。
在运行 XE 会话寻找编译后,我们每秒看到数千次编译。
该系统使用触发器来审计更改。大多数编译是由于触发器。触发器参考 sys.dm_tran_active_transactions。
我们的第一个想法是可能在触发器中引用 DMV 会导致它每次编译,或者可能只是这个特定的 DMV 会导致它。所以我开始测试这个理论。它每次都会编译,但我没有检查触发器是否在每次触发时编译,当它不引用 DMV 而是硬编码一个值时。每次触发时它仍在编译。删除触发器会停止编译。
复制脚本:
CREATE TABLE t1 (transaction_id int, Column2 varchar(100));
CREATE TABLE t2 (Column1 varchar(max), Column2 varchar(100));
GO
CREATE TRIGGER t2_ins
ON t2
AFTER INSERT
AS
INSERT INTO t1
SELECT (SELECT TOP 1 transaction_id FROM sys.dm_tran_active_transactions), Column2
FROM inserted;
GO
--Both of these show compilation events
INSERT INTO t2 VALUES ('row1', 'value1');
INSERT INTO …Run Code Online (Sandbox Code Playgroud) 我们有一个写大量产品的数据库。我们刚刚购买了一台带有 SSD 的新服务器机器来提供帮助。令我们惊讶的是,插入速度并不比存储速度慢得多的旧机器快。在基准测试期间,我们注意到 SQL Server 进程表现出的 IO 率非常低。
例如,我运行了在此页面上找到的脚本,只是在循环中添加了 BEGIN TRAN 和 COMMIT。我最多只能看到磁盘使用率达到 7Mb/s,而 CPU 几乎没有达到 5%。服务器安装了 64Gb 并使用了 10 个。第一次调用的总运行时间为 2 分 15 秒,后续调用大约需要 1 分钟。数据库正在简单恢复并且在测试期间处于空闲状态。我在每次通话之间放下了桌子。
为什么这么简单的脚本这么慢?硬件几乎没有被使用。专用磁盘基准测试工具和 SQLIO 均表明 SSD 以高达 500Mb/s 的读取和写入速度正确执行。我知道随机写入比顺序写入慢,但我希望像这样的简单插入,对没有聚集索引的表,要快得多。
最终我们的场景要复杂得多,但我觉得我需要先了解一个简单的案例。简而言之,我们的应用程序删除旧数据,然后使用 SqlBulkCopy 将新数据复制到临时表,执行一些过滤,最后根据情况使用 MERGE 和/或 INSERT INTO 将数据复制到最终表。
--> 编辑 1:我按照 Martin Smith 链接的程序进行操作,得到以下结果:
[Wait Type] [Wait Count] [Total Wait (ms)] [T. Resource Wait (ms)] [T. Signal Wait (ms)]
NETWORK_IO 5008 46735 46587 148
LOGBUFFER 901 5994 5977 17
PAGELATCH_UP 40 866 865 1 …Run Code Online (Sandbox Code Playgroud) 我有 2 个存储过程,其中第二个存储过程是第一个的改进。
我正试图通过究竟有多少改进来衡量。
clock time由于执行时间不同,因此测量似乎不是一种选择。更糟糕的是,有时(很少,但确实发生过)第二个存储过程的执行时间比第一个过程的执行时间大(我猜是因为当时服务器的工作量)。
Include client statistics 也提供不同的结果。
DBCC DROPCLEANBUFFERS,DBCC FREEPROCCACHE很好,但同样的故事......
SET STATISTICS IO ON 可能是一种选择,但是由于我的存储过程中涉及许多表,我怎么能获得总分呢?
Include actual execution plan也可以是一个选择。我得到estimated subtreecost的0.3253的第一个存储过程,以及0.3079为第二个。我可以说第二个存储过程快 6% (=0.3253/0.3079) 吗?
使用 SQL Server Profiler 中的“读取”字段?
那么我怎么能说第二个存储过程比第一个过程快 x%,无论执行条件如何(服务器的工作量,执行这些存储过程的服务器等)?
如果不可能,我如何证明第二个存储过程比第一个存储过程具有更好的执行时间?
performance ×10
sql-server ×8
index ×1
innodb ×1
join ×1
maintenance ×1
memory ×1
mysql ×1
percona ×1
trigger ×1