如果我的OPTIMIZE FOR UNKNOWN存储过程中有一个,我是否能够看到数据库确定的最佳值?
performance sql-server stored-procedures optimization plan-cache
在某些情况下,我被告知不要对生产中的表执行 VACUUM FULL(或 CLUSTER),因为这将独占锁定它的时间比预期的要长。这同样适用于几个 ALTER TABLE 操作(例如更改几个列的类型)。
提出的替代方案始终是执行以下操作:
CREATE TABLE new_table AS SELECT * FROM old_table ;
-- recreate all indices and constraints
ALTER TABLE old_table RENAME TO going_to_drop_table ;
ALTER TABLE new_table RENAME TO old_table ;
DROP TABLE going_to_drop_table ;
Run Code Online (Sandbox Code Playgroud)
这适用于没有依赖关系的场景old_table(意味着没有任何依赖它的视图,也没有任何外键约束、函数等),并且old_table没有任何插入或更新。但在大多数数据库中,这将是一个例外,而不是规则。
有没有办法在不丢失依赖关系的情况下进行这样的“表交换”?
[为了完整起见:我对如何为 PostgreSQL 9.5 或 9.6 做这件事特别感兴趣]
pg_repack。注意事项:在 Windows 上可能不容易实现,未使用 postgresql 9.6 进行测试。看起来是最有希望的选择。pg_reorg: 类似于 pg_repack(是它的基础)=> 自 postgresql 9.4 以来似乎没有更新,并且它主要被pg_repack.postgresql optimization maintenance online-operations postgresql-9.6
我想请您澄清 mysqltuner 关于 MariaDB 数据库的报告。mysqltuner 是用 --nogood 标志调用的!
>> MySQLTuner 1.7.1 - Major Hayden <major@mhtx.net>
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/
>> Run with '--help' for additional options and output filtering
[--] Skipped version check for MySQLTuner script
[!!] Currently running unsupported MySQL version 10.0.29-MariaDB-0ubuntu0.16.04.1
-------- Log file Recommendations ------------------------------------------------------------------
[--] Log file: (0B)
[!!] Log file doesn't exist
[!!] Log file isn't readable.
-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +Aria +BLACKHOLE +CSV +FEDERATED +InnoDB …Run Code Online (Sandbox Code Playgroud) 在连接后跟 where 子句的情况下,使用子查询来限制结果,然后进行连接会更好吗?例子:
SELECT *
FROM Customers
NATURAL JOIN Orders
WHERE shipped=1
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它接缝 DBMS 将整个客户表与整个订单表连接,然后根据 where 子句过滤结果。使用子查询的等效查询是:
SELECT *
FROM Customers
NATURAL JOIN (SELECT *
FROM Orders
WHERE shipped=1) AS O
Run Code Online (Sandbox Code Playgroud)
在这里,可能有一个较小的 Orders 表要加入。同样,如果有限制客户和订单的 where 子句:
SELECT *
FROM Customers
NATURAL JOIN Orders
WHERE country='US' AND shipped=1
(assuming country attribute belongs to Customers table)
Run Code Online (Sandbox Code Playgroud)
等效的子查询查询:
SELECT *
FROM (SELECT *
FROM Customers
WHERE country='US') AS C
NATURAL JOIN (SELECT *
FROM Orders
WHERE shipped=1) AS O
Run Code Online (Sandbox Code Playgroud) 我有 4 个表,让我们将它们命名为:
(kk - 表示数百万)
我有一个遗留查询,它是这样构造的:
select C.<some_fields>,B.<some_fields>,D.<some_fields> from C
inner join A on C.x = A.x
inner join D on D.z = 123 and D.a_id = A.a_id
inner join B on C.x = B.x and B.z = 123
where A.type = 'Xxx'
Run Code Online (Sandbox Code Playgroud)
此查询非常慢,执行结果最多需要 3 分钟(对于特定情况,它返回 35k 行)。
但是当我将其更改为以下结构时:
with t as (
select C.<some_fields>,D.<some_fields> from C
inner join A on C.x = A.x
inner join D …Run Code Online (Sandbox Code Playgroud) postgresql performance optimization execution-plan amazon-rds query-performance
(这篇文章的后续内容:当我在子查询中 ORDER BY 时,为什么我的 PostgreSQL 表达式索引没有被使用?)
PostgreSQL 9.5。
我不能透露全部细节,但table有 22 列和 5 个索引:
text(btree)text(btree)timestamp with time zone(btree)tsvector(杜松子酒)bigint(btree)(从上一篇文章你知道我试图避免创建这个额外的列,只是使用表达式索引——将两integer列加在一起——没有成功。bigint这里的列可能只是“整数”,但我做了一个创建它时出错;添加列、填充它并重新编制索引花了大约一个小时,所以我希望这不相关,但要提及它以防万一。)
除了tsvector.
以下查询都只需要 12ms 并且只使用一个Index Scan:
SELECT pk FROM table ORDER BY pk DESC LIMIT 10SELECT pk FROM table ORDER BY text_column DESC LIMIT 10SELECT pk FROM table ORDER BY timestamp_column DESC LIMIT 10 …postgresql performance index optimization postgresql-9.5 postgresql-performance
我们有内联函数,可以将数据收集到 XML 中,将派生的 XML 传递给其他函数,然后将其切碎并将其重组为字符串。
(你的“你不应该在 T-SQL 中做那种事情”是另一天的讨论。)
多年来,这在 2005 和 2008 R2 中一直运行良好。我们现在正在升级到 2016 SP1。使用这些函数在我们的生产服务器上运行不到一秒的查询现在在 2016 SP1 中运行得更快。那太好了,但是在 2016 SP1 上编译需要一个小时。严重地:
生产环境:
(它们都来自 SQL Sentry Plan Explorer。)
我们已经在 2008 (100) 和 2016 (130) 兼容性级别尝试了数据库(但我们还没有使用“传统基数估计”和“查询优化器修复”设置,目前这两个设置都为“关闭”)。我们尝试过使用QUERYTRACEON 9481,似乎没有效果。
同样,这与最终的计划无关,因为它们都在很短的时间内运行。这是制定计划所需的时间。
我们已经设法用一组简化的代码在一定程度上重现了这个问题。调用以下示例中的顶级函数的语句在 SQL Server 2016 (SP1-CU5) 上编译需要 30-60 秒,但在 SQL Server 2008 R2 (SP3) 上编译和运行只需不到 1 秒。
/*
Create and populate table...
*/
CREATE TABLE TestXMLStuff (OrderID int, ProdLength int, ProdWidth int, ProdHeight int);
INSERT INTO TestXMLStuff (OrderID, ProdLength, ProdWidth, ProdHeight) …Run Code Online (Sandbox Code Playgroud) I've been running a function on the database that is going into each table, ALTER COLUMN on all columns of a certain data type, and CAST to remove trailing zeros. About 115 tables varying from a few thousand records to a few hundred thousand records. It has been running for almost 24 hours and my approximate calculation until time of completion is about 58 hours.
I have htop up and checking on it regularly.
I should mention this is a …
我有几个关于数据缓存如何工作的问题
想象一下我们有以下情况:
服务器重新启动或我们刚刚运行 DBCC DROPCLEANBUFFERS
我们有一个Table150 GB 并且有列A, B, C, D, E。
列A是聚集索引键,列B和C对他们的非聚集索引。
当我们做
select top 100 * from Table1
Run Code Online (Sandbox Code Playgroud)
整个聚集索引(表)是否从磁盘读取到内存,即使我们只需要 100 行?还是只有 100 行(它们的数据页)从磁盘读取到内存?
与非聚集索引相同,当我们这样做时
select top 100 * from Table1 where column B = 'some value'
Run Code Online (Sandbox Code Playgroud)
整个非聚集索引+聚集索引是否被加载到内存中?或者只有来自非聚集索引的 100 行和来自聚集索引的 100 行?
我们正在对具有大量数据的 SQL Server 数据库运行密集的应用程序负载(数千次操作/秒)。有些表有数十亿行,其中一些有大量插入和更新。
DB 性能一般都还可以,但我们会时不时地遇到查询性能问题;以前运行良好的相当简单的查询可能会突然花费 10-100 倍的时间。
这似乎与表/索引统计信息和查询优化器有关 - 大多数情况下,统计信息更新将解决问题,然后再次更新统计信息会使情况变得更糟(然后重新运行统计信息更新通常会解决问题最终)。
似乎正在发生的事情是优化器决定对某些查询使用客观错误的索引;突然之间,在使用了正确的方法数天和数周之后。
我的问题是:为什么会发生这种情况,我们能做些什么?
这个数据库已经运行了多年,负载基本相同,查询几乎相同,更新量也相同。对于 99.995% 的查询,应该没有理由随着时间的推移决定不同的索引策略,无论输入如何(而且 - 实际上 - 这样做会明显地完全破坏查询性能)。
如上所述,按计划自动更新统计数据通常会产生可怕的问题——如果统计样本出现偏差(这似乎至少有 5% 的情况发生),我们最终会陷入痛苦的世界。
有没有办法告诉SQL Server(在某些表上)统计直方图和密度不会随时间变化,所以请继续对涉及该表的查询使用相同的查询计划?如果不是,我们如何确保随着时间的推移统计更新的可预测结果(避免上述的偏斜统计问题)?
没有存储过程。我们确实可以控制 SQL,因此它可能会被更改,但它有很多代码,因此如果我们必须更改每个查询(例如添加附加子句),那将是不幸的。
一个后续问题:参数嗅探似乎只与存储过程相关,对吗?
optimization ×10
performance ×4
postgresql ×4
sql-server ×4
memory ×2
amazon-rds ×1
cache ×1
centos ×1
cpu ×1
functions ×1
index ×1
innodb ×1
maintenance ×1
mariadb ×1
mysql ×1
mysqltuner ×1
plan-cache ×1
statistics ×1
subquery ×1
xml ×1