我一直在努力理解如何处理在这种情况下经常出现的特定类型的性能问题:当您想在查询中应用多个过滤器,但您知道第一个过滤器将返回一个非常小的数字时来自一个非常大的表的行。
例如,我们有一个包含 10M+ 行的 3rd-party 异构表,其中的列根据TYPEID. 这是一个示例查询:
SELECT ID, NAME, INT109 FROM DATA WHERE TYPEID = 8301514 AND INT109 = 1
Run Code Online (Sandbox Code Playgroud)
在此查询中,两个过滤器没有覆盖索引,但在 'TYPEID' 列上有一个索引。令人困惑的是,即使表中的 10M 中只有大约 500 行TYPEID = 8301514,但此查询有时需要很多秒才能运行。
如果我只是INT109 = 1在最后删除过滤器,查询几乎立即运行:
SELECT ID, NAME, INT109 FROM DATA WHERE TYPEID = 8301514
Run Code Online (Sandbox Code Playgroud)
对我来说,使用较少的过滤器会使查询运行得更快是没有意义的。此外,行为似乎不一致 - 如果第一个查询已经运行多次,它也可以运行得非常快,就像正在缓存某些东西一样。很难做可靠的实验(这是在 SQL Azure 中)。这是正常行为吗?这是否是由错误的执行计划(即使我没有使用参数)或过时的统计数据引起的?
performance sql-server optimization condition azure-sql-database
我正在使用 Postgres 9.1 我要加入两个表:
wikidb=> \d page
Table "public.page"
Column | Type | Modifiers
-----------------------+---------------+------------------------------
page_id | bigint | not null
page_namespace | integer | not null default 0
page_title | text | not null default ''::text
[...]
Indexes:
[...]
"page_page_namespace_page_title_idx" UNIQUE, btree (page_namespace, page_title)
wikidb=> \d pagelinks
Table "public.pagelinks"
Column | Type | Modifiers
-------------------+---------+----------------------------
pl_from | bigint | not null default 0::bigint
pl_namespace | integer | not null default 0
pl_title | text | not null default ''::text …Run Code Online (Sandbox Code Playgroud) postgresql performance optimization execution-plan postgresql-9.1 query-performance
我正在使用事实表源查询,我观察到查询的性能很糟糕。只需在 select 子句中使用一个转换日期格式的函数,它就从 1:00 分钟增加到 6:30 分钟。它只有 7 个表在简单的条件下连接(没有疯狂的东西)。
展望未来,我需要向连接列表添加更多的表。这只会使性能变得更糟。在开始添加之前,我需要对当前查询进行微调。
这是查询:
SELECT [dbo].[dFK](oew.StartDate) AS StartDate, -- INTEGER DATE!
[dbo].[dFK](oew.EndDate) AS EndDate,
[dbo].[dFK](oew.EffectiveDate) AS EffectiveDate
FROM OpenEnrollmentWindow oew
INNER JOIN ProductYear py ON oew.OrganizationProductYearID = py.ID
INNER JOIN Marketplace m ON py.MarketplaceID = m.ID
INNER JOIN Organization o ON m.OrganizationID = o.ID
INNER JOIN Consumer c ON c.OrganizationID = o.ID
LEFT JOIN OpenEnrollmentWindowProduct oewp ON oew.ID = oewp.OrganizationOpenEnrollmentWindowID
LEFT JOIN OpenEnrollmentWindowProductType oewpt ON oew.ID = oewpt.OrganizationOpenEnrollmentWindowID
Run Code Online (Sandbox Code Playgroud)
下面是函数的定义:
CREATE FUNCTION [dbo].[dFK]
(@dt …Run Code Online (Sandbox Code Playgroud) 我正在测试 sql server 中的合并加入。我有一个INNER JOIN并强制优化器执行以下操作MERGE JOIN:
ID 在个人表中是主键ID 在 Abteilung 表是主键这些表中没有其他索引
select * from [dbo].[Personal] as P inner join [dbo].[Abteilung] as A
on P.[ID]= A.[Personal_ID] OPTION (MERGE JOIN)
Run Code Online (Sandbox Code Playgroud)然后优化器使用这个计划来运行我的查询:
我想强制优化器使用index seek而不是Table Scan
我为实现这个目标做了什么:
ID,上定义分组索引Personal_ID。如果我运行查询,执行计划是这样的变化:这里我有聚集索引扫描,但没有聚集索引搜索
FORCESEEK提示。如果我使用此提示,运行查询会发生错误:由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用 SET FORCEPLAN 的情况下重新提交查询。
如果我在查询中添加 where 子句,则查询将更改为:
select * from [dbo].[Personal] as P inner join [dbo].[Abteilung] as A
on P.[ID]= A.[Personal_ID] where A.[Personal_ID]=2
OPTION (MERGE JOIN) …Run Code Online (Sandbox Code Playgroud)我在视图中有一个非常大的查询(让我们称之为a_sql),这真的很快,除非我ORDER BY在SELECT带有小的外部使用LIMIT:
SELECT
customs.id AS custom_id, customs.custom_name AS custom_name, customs.slug AS slug, customs.use_case AS custom_use_case,
SUM(CASE WHEN designers.id = orders.user_id AND orders.bulk = 't' THEN order_rows.quantity ELSE 0 END) AS sale_bulk,
SUM(CASE WHEN designers.id = orders.user_id AND orders.bulk = 'f' THEN order_rows.quantity ELSE 0 END) AS sale_not_bulk,
SUM(CASE WHEN designers.id = orders.user_id THEN order_rows.quantity ELSE 0 END) AS sale_total,
SUM(CASE WHEN designers.id <> orders.user_id AND orders.bulk = 't' THEN order_rows.quantity ELSE 0 …Run Code Online (Sandbox Code Playgroud) postgresql performance optimization view postgresql-9.4 postgresql-performance
假设我有这个查询:
SELECT EMP_ID,LAST_NAME FROM EMPLOYEES
WHERE POSITIONID IN (1,3) ORDER BY POSITIONID,LAST_NAME;
Run Code Online (Sandbox Code Playgroud)
现在如果我只想显示 50 到 60 之间的前十行,我能想到的唯一方法是首先使用 ROWNUM 伪列运行上面的查询,然后从这个查询的结果中进行选择。像这样的东西:
SELECT EMP_ID,LAST_NAME FROM
(SELECT ROWNUM RNUM,EMP_ID,LAST_NAME FROM
(SELECT EMP_ID,LAST_NAME FROM EMPLOYEES
WHERE POSITIONID IN (1,3) ORDER BY POSITIONID,LAST_NAME))
WHERE RNUM BETWEEN 50 AND 60;
Run Code Online (Sandbox Code Playgroud)
但是这样,我最终会首先获取职位为 1 或 3 的所有员工,然后提取其中的 10 行。我觉得这有点低效。有没有办法在不先进行全面扫描的情况下实现这一目标?
我已经运行了一个多小时的服务器端配置文件跟踪,以生成一个 .trc 文件,其中包含我的一个数据库中的所有活动。
然后,我将此 .trc 跟踪文件作为参数传递给数据库引擎优化顾问。
运行 DTA 后,我得到了建议:
我正在使用SQL Server 2005,除了单独编写脚本之外,我似乎找不到任何其他方法,这太耗时了。
互联网上有查询发现坏索引
虽然他们的逻辑很简单
如果写入计数 > 读取计数 = 坏索引
这是一个示例查询
SELECT OBJECT_NAME(s.object_id) AS 'Table Name',
i.name AS 'Index Name',
i.index_id,
user_updates AS 'Total Writes',
user_seeks + user_scans + user_lookups AS 'Total Reads',
user_updates - ( user_seeks + user_scans + user_lookups ) AS 'Difference'
FROM sys.dm_db_index_usage_stats AS s WITH ( NOLOCK )
INNER JOIN sys.indexes AS i WITH ( NOLOCK ) ON s.object_id = i.object_id
AND i.index_id = s.index_id
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
AND s.database_id = DB_ID()
AND user_updates > ( user_seeks …Run Code Online (Sandbox Code Playgroud) performance sql-server optimization index-tuning sql-server-2014 performance-tuning
这可以通过在查询选项中调用跟踪标志 8649 来完成。
OPTION (QUERYTRACEON 8649)
此跟踪标志导致查询的成本为 0,这将始终低于并行性的成本阈值,因此该查询将被视为并行计划。
试图以这种方式强制 T-SQL 查询使用并行性是否有任何缺点?
performance sql-server optimization parallelism t-sql query-performance
所以我有一个带有多个 CPU 内核的服务器,它安装了一个数据库。你认为如果我们用docker安装多个数据库(数据分片),那么每个请求都会去不同的数据库是个好主意吗?每个数据库中的数据都不同,并且根据来自客户端的请求,它将查询不同的数据库。
我不知道这会比包含所有数据的专用数据库更糟糕吗?
performance sql-server optimization clustering sharding query-performance
optimization ×10
performance ×7
sql-server ×7
postgresql ×2
clustering ×1
condition ×1
index ×1
index-tuning ×1
oracle ×1
oracle-11g ×1
parallelism ×1
row ×1
sharding ×1
statistics ×1
t-sql ×1
view ×1