标签: query-performance

如何处理由范围类型完全相等引起的错误查询计划?

我正在执行更新,我需要一个tstzrange变量完全相等。修改了大约 100 万行,查询需要大约 13 分钟。的结果EXPLAIN ANALYZE可以在这里看到,实际结果与查询计划器估计的结果有很大的不同。问题是索引扫描t_range期望返回单行。

这似乎与范围类型的统计信息与其他类型的统计信息的存储方式有关。pg_stats查看列的视图,n_distinct是 -1,其他字段(例如most_common_valsmost_common_freqs)为空。

但是,必须在t_range某处存储统计信息。我在 t_range 上使用 'within' 而不是完全相等的极其相似的更新需要大约 4 分钟才能执行,并且使用了完全不同的查询计划(请参阅此处)。第二个查询计划对我来说很有意义,因为将使用临时表中的每一行和历史表的很大一部分。更重要的是,查询规划器为 上的过滤器预测了近似正确的行数t_range

的分布t_range有点不寻常。我正在使用这个表来存储另一个表的历史状态,并且对另一个表的更改在大转储中同时发生,因此没有很多不同的t_range. 以下是与 的每个唯一值对应的计数t_range

                              t_range                              |  count  
-------------------------------------------------------------------+---------
 ["2014-06-12 20:58:21.447478+00","2014-06-27 07:00:00+00")        |  994676
 ["2014-06-12 20:58:21.447478+00","2014-08-01 01:22:14.621887+00") |   36791
 ["2014-06-27 07:00:00+00","2014-08-01 07:00:01+00")               | 1000403
 ["2014-06-27 07:00:00+00",infinity)                               |   36791
 ["2014-08-01 07:00:01+00",infinity)                               |  999753
Run Code Online (Sandbox Code Playgroud)

t_range上面distinct的计数是完整的,所以基数是~3M(其中~1M会受到任一更新查询的影响)。

为什么查询 1 的性能比查询 2 …

postgresql performance postgresql-9.3 range-types query-performance

29
推荐指数
2
解决办法
1162
查看次数

对聚合使用索引视图 - 好得令人难以置信?

我们有一个具有相当大记录数(10-2000 万行)的数据仓库,并且经常运行查询来计算特定日期之间的记录数,或者计算具有特定标志的记录数,例如

SELECT
    f.IsFoo,
    COUNT(*) AS WidgetCount
FROM Widgets AS w
JOIN Flags AS f
    ON f.FlagId = w.FlagId
WHERE w.Date >= @startDate
GROUP BY f.IsFoo
Run Code Online (Sandbox Code Playgroud)

性能并不差,但可能相对缓慢(在冷缓存上可能 10 秒)。

最近我发现我可以GROUP BY在索引视图中使用,因此尝试了类似于以下内容

CREATE VIEW TestView
WITH SCHEMABINDING
AS
    SELECT
        Date,
        FlagId,
        COUNT_BIG(*) AS WidgetCount
    FROM Widgets
    GROUP BY Date, FlagId;
GO

CREATE UNIQUE CLUSTERED INDEX PK_TestView ON TestView
(
    Date,
    FlagId
);
Run Code Online (Sandbox Code Playgroud)

因此,我的第一个查询的性能现在 < 100 毫秒,结果视图和索引 < 100k(尽管我们的行数很大,但日期和标志 ID 的范围意味着此视图仅包含 1000-2000 行)。

我认为这可能会降低对 Widget 表的写入性能,但没有 - 据我所知,向该表中插入和更新的性能几乎不受影响(另外,作为数据仓库,该表很少更新反正)

对我来说,这似乎好得令人难以置信——是吗?以这种方式使用索引视图时需要注意什么?

performance index sql-server materialized-view query-performance

29
推荐指数
2
解决办法
1万
查看次数

空间索引可以帮助“范围-排序-限制”查询吗

问这个问题,特别是针对 Postgres,因为它对 R 树/空间索引有很好的支持。

我们有下表,其中包含单词及其频率的树结构(嵌套集模型):

lexikon
-------
_id   integer  PRIMARY KEY
word  text
frequency integer
lset  integer  UNIQUE KEY
rset  integer  UNIQUE KEY
Run Code Online (Sandbox Code Playgroud)

和查询:

SELECT word
FROM lexikon
WHERE lset BETWEEN @Low AND @High
ORDER BY frequency DESC
LIMIT @N
Run Code Online (Sandbox Code Playgroud)

我认为覆盖索引(lset, frequency, word)会很有用,但我觉得如果范围内的lset值太多,它可能表现不佳(@High, @Low)

(frequency DESC)有时,当使用该索引的搜索早期产生@N与范围条件匹配的行时,一个简单的索引也可能就足够了。

但似乎性能在很大程度上取决于参数值。

有没有办法让它快速执行,不管范围(@Low, @High)是宽还是窄,也不管高频词是否幸运地在(窄)选择的范围内?

R-tree/空间索引有帮助吗?

添加索引,重写查询,重新设计表,没有限制。

postgresql performance index database-design query-performance

28
推荐指数
2
解决办法
4312
查看次数

SQL Server 2014:对不一致的自连接基数估计有什么解释?

考虑 SQL Server 2014 中的以下查询计划:

在此处输入图片说明

在查询计划中,自联接ar.fId = ar.fId产生 1 行的估计值。然而,这是一个逻辑上不一致的估计:ar20,608行和只有一个不同的值fId(准确地反映在统计数据中)。因此,此连接会生成行 ( ~424MMrows)的完整叉积,从而导致查询运行数小时。

我很难理解为什么 SQL Server 会得出一个很容易证明与统计数据不一致的估计值。有任何想法吗?

初步调查和其他细节

根据 Paul在此处回答,用于估计连接基数的 SQL 2012 和 SQL 2014 启发式方法似乎都应该可以轻松处理需要比较两个相同直方图的情况。

我从跟踪标志 2363 的输出开始,但不太容易理解。请问下面的片段意味着SQL Server在比较直方图fIdbId以估计选择性的只加入使用fId?如果是这样,那显然是不正确的。还是我误读了跟踪标志输出?

Plan for computation:
  CSelCalcExpressionComparedToExpression( QCOL: [ar].fId x_cmpEq QCOL: [ar].fId )
Loaded histogram for column QCOL: [ar].bId from stats with id 3
Loaded histogram for column QCOL: [ar].fId from stats with id 1 …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan sql-server-2014 cardinality-estimates query-performance

28
推荐指数
1
解决办法
759
查看次数

如何加快选择不同的?

我在一些时间序列数据上有一个简单的选择:

SELECT DISTINCT user_id
FROM events
WHERE project_id = 6
AND time > '2015-01-11 8:00:00'
AND time < '2015-02-10 8:00:00';
Run Code Online (Sandbox Code Playgroud)

它需要112秒。这是查询计划:

http://explain.depesz.com/s/NTyA

我的应用程序必须执行许多不同的操作并像这样计数。有没有更快的方法来获取这种数据?

postgresql performance optimization postgresql-9.3 amazon-rds query-performance

25
推荐指数
2
解决办法
4万
查看次数

如何在大表上使用 LEFT JOIN 优化非常慢的 SELECT

我在谷歌上搜索、自我教育和寻找解决方案几个小时,但没有运气。我在这里发现了一些类似的问题,但不是这种情况。

我的表:

  • 人(约 1000 万行)
  • 属性(位置,年龄,...)
  • 人员和属性之间的链接 (M:M)(约 40M 行)

完全转储 ~280MB

情况: 我尝试person_id从某些位置 ( location.attribute_value BETWEEN 3000 AND 7000) 中选择所有人员 ID ( ) ,具有某种性别 ( gender.attribute_value = 1),出生于某些年份 ( bornyear.attribute_value BETWEEN 1980 AND 2000) 并且具有某种眼睛颜色 ( eyecolor.attribute_value IN (2,3))。

这是我的查询女巫花了3~4 分钟。我想优化:

SELECT person_id
FROM person
    LEFT JOIN attribute location ON location.attribute_type_id = 1 AND location.person_id = person.person_id
    LEFT JOIN attribute gender ON gender.attribute_type_id = 2 AND gender.person_id = person.person_id
    LEFT JOIN …
Run Code Online (Sandbox Code Playgroud)

mysql performance optimization eav query-performance

25
推荐指数
2
解决办法
10万
查看次数

两个日期列的 SARGable WHERE 子句

对我来说,我有一个关于 SARGability 的有趣问题。在这种情况下,它是关于对两个日期列之间的差异使用谓词。这是设置:

USE [tempdb]
SET NOCOUNT ON  

IF OBJECT_ID('tempdb..#sargme') IS NOT NULL
BEGIN
DROP TABLE #sargme
END

SELECT TOP 1000
IDENTITY (BIGINT, 1,1) AS ID,
CAST(DATEADD(DAY, [m].[severity] * -1, GETDATE()) AS DATE) AS [DateCol1],
CAST(DATEADD(DAY, [m].[severity], GETDATE()) AS DATE) AS [DateCol2]
INTO #sargme
FROM sys.[messages] AS [m]

ALTER TABLE [#sargme] ADD CONSTRAINT [pk_whatever] PRIMARY KEY CLUSTERED ([ID])
CREATE NONCLUSTERED INDEX [ix_dates] ON [#sargme] ([DateCol1], [DateCol2])
Run Code Online (Sandbox Code Playgroud)

我会经常看到的是这样的:

/*definitely not sargable*/
SELECT
    * ,
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
    [#sargme] AS [s] …
Run Code Online (Sandbox Code Playgroud)

performance index sql-server query-performance

25
推荐指数
3
解决办法
3116
查看次数

消除会降低性能的键查找(集群)运算符

如何消除执行计划中的 Key Lookup (Clustered) 运算符?

tblQuotes已经有一个聚集索引 (on QuoteID) 和 27 个非聚集索引,所以我不想再创建了。

我将聚集索引列QuoteID放在我的查询中,希望它会有所帮助 - 但不幸的是仍然相同。

执行计划在这里

或查看它:

在此处输入图片说明

这是 Key Lookup 运算符所说的:

在此处输入图片说明

询问:

declare
        @EffDateFrom datetime ='2017-02-01',
        @EffDateTo   datetime ='2017-08-28'

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

IF OBJECT_ID('tempdb..#Data') IS NOT NULL
    DROP TABLE #Data 
CREATE TABLE #Data
(
    QuoteID int NOT NULL,   --clustered index

    [EffectiveDate] [datetime] NULL, --not indexed
    [Submitted] [int] NULL,
    [Quoted] [int] NULL,
    [Bound] [int] NULL,
    [Exonerated] [int] NULL,
    [ProducerLocationId] [int] …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan sql-server-2012 bookmark-lookup query-performance

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

为什么不使用 IS NULL 值上的过滤索引?

假设我们有一个像这样的表定义:

CREATE TABLE MyTab (
    ID INT IDENTITY(1,1) CONSTRAINT PK_MyTab_ID PRIMARY KEY
    ,GroupByColumn NVARCHAR(10) NOT NULL
    ,WhereColumn DATETIME NULL
    )
Run Code Online (Sandbox Code Playgroud)

还有一个过滤的非聚集索引,如下所示:

CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn ON MyTab 
    (GroupByColumn)
WHERE (WhereColumn IS NULL) 
Run Code Online (Sandbox Code Playgroud)

为什么这个索引没有“覆盖”这个查询:

SELECT 
    GroupByColumn
    ,COUNT(*)
FROM MyTab
WHERE WhereColumn IS NULL
GROUP BY GroupByColumn
Run Code Online (Sandbox Code Playgroud)

我得到这个执行计划:

在此处输入图片说明

KeyLookup 用于 WhereColumn IS NULL 谓词。

这是计划:https : //www.brentozar.com/pastetheplan/?id=SJcbLHxO7

performance sql-server index-tuning filtered-index query-performance

23
推荐指数
2
解决办法
4299
查看次数

无重复组合的 SQL 查询

我需要一个可以在(或作为)函数中使用并检索 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)

performance sql-server query-performance

22
推荐指数
1
解决办法
3万
查看次数