标签: performance

内联变量时,为什么 SQL Server 使用更好的执行计划?

我有一个要优化的 SQL 查询:

DECLARE @Id UNIQUEIDENTIFIER = 'cec094e5-b312-4b13-997a-c91a8c662962'

SELECT 
  Id,
  MIN(SomeTimestamp),
  MAX(SomeInt)
FROM dbo.MyTable
WHERE Id = @Id
  AND SomeBit = 1
GROUP BY Id
Run Code Online (Sandbox Code Playgroud)

MyTable 有两个索引:

CREATE NONCLUSTERED INDEX IX_MyTable_SomeTimestamp_Includes
ON dbo.MyTable (SomeTimestamp ASC)
INCLUDE(Id, SomeInt)

CREATE NONCLUSTERED INDEX IX_MyTable_Id_SomeBit_Includes
ON dbo.MyTable (Id, SomeBit)
INCLUDE (TotallyUnrelatedTimestamp)
Run Code Online (Sandbox Code Playgroud)

当我完全按照上面写的方式执行查询时,SQL Server 扫描第一个索引,导致 189,703 次逻辑读取和 2-3 秒的持续时间。

当我内联@Id变量并再次执行查询时,SQL Server 寻找第二个索引,导致只有 104 次逻辑读取和 0.001 秒的持续时间(基本上是即时的)。

我需要变量,但我希望 SQL 使用好的计划。作为临时解决方案,我在查询上放置了索引提示,查询基本上是即时的。但是,我尽量避免使用索引提示。我通常假设如果查询优化器无法完成它的工作,那么我可以做(或停止做)一些事情来帮助它,而无需明确告诉它该做什么。

那么,当我内联变量时,为什么 SQL Server 会提出更好的计划?

performance sql-server execution-plan

33
推荐指数
2
解决办法
6205
查看次数

33
推荐指数
1
解决办法
3872
查看次数

当我向它们添加 WHERE 子句时,视图是否被优化?

如果您在视图内部或外部过滤视图会有所不同吗?

例如,这两个查询之间有什么区别吗?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1
Run Code Online (Sandbox Code Playgroud)

或者

SELECT Id
FROM MyView
WHERE SomeColumn = 1
Run Code Online (Sandbox Code Playgroud)

并且MyView定义为

SELECT Id, SomeColumn
FROM MyTable
Run Code Online (Sandbox Code Playgroud)

如果源表位于链接服务器上,答案有什么不同吗?

我问是因为我必须从链接服务器两次查询一个大表(4400 万行),并获得结果的汇总。我想知道是否应该创建两个视图来访问数据,每个查询一个视图,或者我是否可以使用单个视图和一个WHERE子句。

performance sql-server-2005 sql-server view query-performance

32
推荐指数
2
解决办法
3万
查看次数

日期索引优化

我在 PostgreSQL 9.0.8 中有一个很大的对象表(15M+ 行),我想查询过时的字段。

出于可扩展性和并发性的目的,我想将查询除以数百万,并且我想获取具有几天前日期的 updated_at 字段的所有数据。

我已经在 100 万个 ID 上尝试了许多索引和查询,但使用 Heroku 的 Ronin 硬件似乎无法在 100 秒内获得性能。

我正在寻找我尚未尝试使其尽可能高效的建议。

尝试 #1

 EXPLAIN ANALYZE SELECT count(*) FROM objects
 WHERE (date(updated_at)) < (date(now())-7) AND id >= 5000001 AND id < 6000001;
 INDEX USED: (date(updated_at),id)
 268578.934 ms
Run Code Online (Sandbox Code Playgroud)

尝试 #2

 EXPLAIN ANALYZE SELECT count(*) FROM objects
 WHERE ((date(now()) - (date(updated_at)) > 7)) AND id >= 5000001 AND id < 6000001;
 INDEX USED: primary key
 335555.144 ms
Run Code Online (Sandbox Code Playgroud)

尝试 #3

 EXPLAIN ANALYZE SELECT count(*) FROM …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index partitioning postgresql-performance

32
推荐指数
1
解决办法
5万
查看次数

MySQL 在磁盘上创建临时表。我该如何阻止?

我们正在运行一个网站(Moodle),用户目前发现它很慢。我想我已经将问题追溯到 MySQL 在磁盘上创建临时表。我created_tmp_disk_tables在 Mysql Workbench 服务器管理中观察了这个变量,这个数字以大约 50 个表/秒的速度增加。经过一天的使用,created_tmp_disk_tables是> 100k。此外,内存似乎没有被释放。使用量不断增加,直到系统变得几乎无法使用,我们必须重新启动 MySQL。我几乎每天都需要重新启动它,从使用大约 30-35% 的可用内存开始,并以 80% 结束一天。

我在数据库中没有 blob,也无法控制查询,因此我无法尝试优化它们。我还使用了Percona 配置向导来生成配置文件,但是 my.ini 也没有解决我的问题。

问题

  1. 我应该更改什么来阻止 MySQL 在磁盘上创建临时表?我需要更改哪些设置?我应该给它扔更多的内存吗?

  2. 如何阻止 MySQL 占用我的内存?

编辑

我启用了slow_queries日志并发现查询SELECT GET_LOCK() 被记录为缓慢。快速搜索显示我在 PHP 配置 ( mysqli.allow_persistent = ON) 中允许持久连接。我关掉了这个。这降低了 MySQL 消耗内存的速度。它仍然在创建临时表。

我还检查了它key_buffer size是否足够大。我看着变量key_writes。这应该为零。如果没有,请增加key_buffer_size.I 有零key_reads和零,key_writes因此我认为key_buffer_size足够大。

我将tmp_table_sizemax-heap-table-size增加到 1024M,因为 created_tmp_disk_tables 的增加可能表明这些表无法放入内存。这并没有解决它。

参考:http : //www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

编辑 2

如果您sort_merge_passes …

mysql performance windows database-tuning temporary-tables

32
推荐指数
2
解决办法
9万
查看次数

XML 索引的性能非常奇怪

我的问题基于此:https : //stackoverflow.com/q/35575990/5089204

为了在那里给出答案,我做了以下测试场景。

测试场景

首先我创建一个测试表并用 100.000 行填充它。一个随机数(0 到 1000)应该为每个随机数产生 ~100 行。这个数字被放入一个 varchar col 并作为一个值放入您的 XML。

然后我做一个像 OP 那样的调用,需要它使用 .exist() 和 .nodes() ,第二个有一个小优势,但都需要 5 到 6 秒。事实上,我调用了两次:第二次以交换的顺序和稍微改变的搜索参数和“//item”而不是完整路径来避免通过缓存结果或计划产生误报。

然后我创建一个 XML 索引并执行相同的调用

现在 - 真正让我感到惊讶的是什么!-在.nodes完整路径是比以前(9秒)慢得多,但.exist()下降到半秒,用全路径甚至下降到约0.10秒。(同时.nodes()具有短的路径比较好,但仍远远落后于.exist()

问题:

我自己的测试简而言之:XML 索引可以极大地破坏数据库。它们可以极大地加快速度(s.edit 2),但也可以减慢您的查询速度。我想了解它们是如何工作的...什么时候应该创建一个 XML 索引?为什么.nodes()有索引比没有索引更糟糕?如何避免负面影响?

CREATE TABLE #testTbl(ID INT IDENTITY PRIMARY KEY, SomeData VARCHAR(100),XmlColumn XML);
GO

DECLARE @RndNumber VARCHAR(100)=(SELECT CAST(CAST(RAND()*1000 AS INT) AS VARCHAR(100)));

INSERT INTO #testTbl VALUES('Data_' + …
Run Code Online (Sandbox Code Playgroud)

performance xml sql-server sql-server-2012

32
推荐指数
1
解决办法
4493
查看次数

32
推荐指数
2
解决办法
3567
查看次数

哪里可以找到mysql的慢日志?

正如标题所说,我在哪里可以看到它?

是否有任何配置选项(例如多少毫秒可以确定查询是否缓慢)?

mysql performance slow-log

31
推荐指数
3
解决办法
6万
查看次数

高效插入带有聚集索引的表

我有一个 SQL 语句,该语句将行插入到表中,并且在 TRACKING_NUMBER 列上具有聚集索引。

例如:

INSERT INTO TABL_NAME (TRACKING_NUMBER, COLB, COLC) 
SELECT TRACKING_NUMBER, COL_B, COL_C 
FROM STAGING_TABLE
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 在聚集索引列的 SELECT 语句中使用 ORDER BY 子句是否有帮助,或者是否会因 ORDER BY 子句所需的额外排序而否定任何获得的收益?

performance sql-server clustered-index insert

31
推荐指数
3
解决办法
7万
查看次数

mysql dump import 在我的开发人员的机器上非常慢

我有一个 SQL 转储,它非常大(411 MB),在服务器 A 上导入需要 10 分钟,我的工作站 B 上的相同导入估计(pipeviewer)需要 8 小时才能导入(它在 40 分钟内导入了 31 MB ) 所以这是慢了 53 倍。

规格:

Server A:
   MySQL Version: 5.5.30-1.1 (Debian)
   2 GB RAM
   1 core QEMU Virtual CPU version 1.0 - cpu MHz: 3400.020

Workstation B: 
   MySQL Version: 5.5.41-MariaDB-1ubuntu0.14.04.1
   14 GB RAM
   4 cores Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz - cpu MHz: 1600.000
Run Code Online (Sandbox Code Playgroud)

mysql/maria 配置是库存配置。

我昨天在我的工作站上切换到 MariaDB - 但在 MariaDB 之前,统计数据更糟。

我已经删除了工作站上的所有数据库 - 没有区别。

最大的问题是:性能怎么会慢 53 倍?我不能这样工作:-(

我的导入命令:

pv sql/master.sql …
Run Code Online (Sandbox Code Playgroud)

mysql performance

31
推荐指数
3
解决办法
6万
查看次数