标签: optimization

第二个计算标量的解释

我注意到一个奇怪的事情。这个查询

declare @t int = 3;

select distinct top(@t) 
    Number - Number + ABS(CHECKSUM( CAST(NEWID() as binary(16)) ))
from Numbers as n;
Run Code Online (Sandbox Code Playgroud)

制定这个计划

在此输入图像描述

dbo.Numbers 是一个标准的 Numbers 表 - 只是具有聚集主键的连续整数列表 - 包含 100k 行。

有两个计算标量运算符。右边的计算Number - Number并定义一个内部表达式。左边的执行加法和内部函数调用。奇怪的是,如果重写为,则只有一个计算标量运算符

Number + ABS(...) - Number
Run Code Online (Sandbox Code Playgroud)

这里发生了一些“有趣”的事情吗?或者这是解析器如何从备忘录构建执行计划的简单产物?两种形式都在 search(1) 中完成编译。使用 TF8677 强制搜索(2) 不会改变行为。TF8606 显示项目标准化后树中的分离。

我不认为这是一个问题。我只是想知道这里是否有值得学习的东西。

一些背景

我想生成一个固定长度的随机数列表。这

ABS(CHECKSUM(NEWID()))
Run Code Online (Sandbox Code Playgroud)

似乎是要走的路。我有一个 Numbers 表(有 100k 行),因此使用它来驱动输出似乎是合理的。我想要不进行替换的采样,因此 DISTINCT 将确保没有重复项,并且 TOP() 将给出所需的结果集大小。把它放在一起我得到

declare @t int = 3;

select distinct top(@t) 
    ABS(CHECKSUM(NEWID()))
from Numbers as n;
Run Code Online (Sandbox Code Playgroud)

遗憾的是,该计划是使用哈希匹配(聚合)进行聚集索引扫描。最好只读取所需的最小行数,也许可以使用 Flow Distinct 来强制唯一性。 …

sql-server optimization sql-server-2019

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

Postgres NOT NULL 优化

我正在尝试优化这个 SQL 查询:

select topics.id from "topics"
     left join "articles_topics" on "topics"."id" = "articles_topics"."topic_id"
     left join "articles" on "articles_topics"."article_id" = "articles"."id"
where not "topics"."type" = 'sport' and "articles"."image" is not null
group by "topics"."id"
having COUNT(articles.id) > 10
Run Code Online (Sandbox Code Playgroud)

这是完整的查询成本(我使用过EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS)

Finalize HashAggregate  (cost=12881.12..12974.90 rows=2501 width=8) (actual time=209.037..210.463 rows=1381 loops=1)
  Output: topics.id
  Group Key: topics.id
  Filter: (count(articles.id) > 10)
  Rows Removed by Filter: 5672
  Buffers: shared hit=8624
  ->  Gather  (cost=12018.39..12843.61 rows=7502 width=16) (actual time=198.146..205.348 rows=10376 loops=1) …
Run Code Online (Sandbox Code Playgroud)

postgresql optimization query-performance

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

优化器如何执行标量函数

我在网上读到,标量函数会影响性能,因为优化器无法访问标量函数的内容。由于该函数是针对每一行执行的,因此优化器是否必须每次都为函数的内容构建执行计划,或者是否在第一次访问该函数时构建该计划,然后将其用于所有其他行?

sql-server optimization functions

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

大量“键值”连接会导致 SQL Server 查询速度呈指数级减慢

我正在从使用对象 ID 和属性类型作为聚集索引的属性表迁移一些存储“键值”样式的数据(我也尝试过作为非聚集索引):

\n
CREATE TABLE [dbo].[#attrs](\n    [DataMigrationEventObjectID] [int] NOT NULL,\n    [AttributeType] [varchar](128) NOT NULL,\n    [AttributeValue] [varchar](255) NULL\n) \nCREATE CLUSTERED INDEX pk ON #attrs ([DataMigrationEventObjectID],AttributeType);\n
Run Code Online (Sandbox Code Playgroud)\n

我添加了属性值来选择值,因为数据库中的属性表有很多其他数据,我可以仅为此迁移事件选择它。使用我的测试数据集来填充此表的查询会插入约 3k 行,并且运行时间不到一秒(我的数据集中总共约有 50 个对象,每个对象都有多个属性)。

\n

查询中表的连接如下所示,连接聚集索引:

\n
        INNER JOIN #attrs obj_gvn\n        ON obj_gvn.DataMigrationEventObjectID = obj.DataMigrationEventObjectID\n        AND obj_gvn.AttributeType = \'GivenName\'\n
Run Code Online (Sandbox Code Playgroud)\n

通过对该临时表进行 14 个联接,查询将在几秒钟内完成。如果有 15 个连接,查询需要一分钟,如果有 16 个以上连接,则半小时后仍在运行。

\n

我已经检查了所有联接是否存在意外条件,这会导致返回太多行,当它在 1 分钟内返回时,它只返回正确的行,所以我不认为存在意外的笛卡尔联接。设置 MAXDOP 值不会影响它,并且查询运行一分钟时返回的查询计划不会标记任何问题。

\n

对于 SQL,我错过了什么,导致它在聚集索引上进行大量联接,理论上应该很快,而且记录数量如此之少?

\n
\n

我无法获得实际执行计划,因为查询未完成,并且因为它使用临时表,所以我无法获得其估计计划。我尝试将临时表捏造为数据库中的真实表并生成估计计划,但 2 分钟后该计划仍未生成,因此看起来延迟是在“创建计划”方面

\n

粘贴查询的缩短版本的计划:brentozar.com/pastetheplan/ ?id=Hy76dd92i

\n

我已经更新了数据库的统计数据以防万一,但它仍然没有生成计划。

\n

我过去处理过越来越多有问题的连接查询,其中计划编译仍然是即时的。我觉得它在“生成计划”步骤失败这一事实一定意味着什么。

\n

不幸的是,更新到最新的 CU 没有帮助。 …

sql-server optimization execution-plan sql-server-2019

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

在哪些字段上建立索引?查询的字段 (WHERE) 或返回的字段 (SELECT)

我在AWS RDS 中型实例上有一个大型 MySQL 数据库表(约 100 万行并且还在增长):

mysql> describe clients;
+-----------------+---------------+------+-----+---------+----------------+
| Field           | Type          | Null | Key | Default | Extra          |
+-----------------+---------------+------+-----+---------+----------------+
| id              | int(11)       | NO   | PRI | NULL    | auto_increment |
| name            | varchar(500)  | YES  |     | NULL    |                |
| address         | varchar(500)  | YES  |     | NULL    |                |
| city            | varchar(200)  | YES  |     | NULL    |                |
| state           | varchar(100)  | YES  | …
Run Code Online (Sandbox Code Playgroud)

mysql optimization explain

0
推荐指数
1
解决办法
112
查看次数

为什么查询优化器不使用负过滤索引

我有一张具有以下结构的表,如您所见,有一个聚集索引和两个非聚集索引,一个非聚集索引是 IX_ParentId_Include,另一个是 FLIX_ParentId_Include

除了第二个索引被过滤之外,它们是相同的。

CREATE TABLE [dbo].[PhotoRepo] (
    [PhotoRepoId]              INT            IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL,
    [TypeId]                   TINYINT        NULL,
    [ParentId]                 INT            NULL,
    [RemoteLocation]           VARCHAR (4000) NOT NULL,
    [UploadedAt]               DATETIME       NOT NULL,
    [UploadedBy]               VARCHAR (255)  NULL,
    [FileSize]                 INT            NOT NULL,
    [DefaultChild]             BIT            NOT NULL,
    [RemoteLocationUploadedAt] DATETIME       NULL,
    CONSTRAINT [PK_FileList] PRIMARY KEY NONCLUSTERED ([PhotoRepoId] ASC)
);


GO
CREATE CLUSTERED INDEX [IX_PhotoRepoId]
    ON [dbo].[PhotoRepo]([PhotoRepoId] ASC);


GO


CREATE NONCLUSTERED INDEX [IX_ParentId_Include]
    ON [dbo].[PhotoRepo]([ParentId] ASC)
    INCLUDE([RemoteLocation], [DefaultChild], [TypeId]);
GO

CREATE NONCLUSTERED INDEX [FLIX_ParentId_Include] …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server optimization query-performance

0
推荐指数
1
解决办法
753
查看次数

加入 4 个表并根据 3 个时间戳选择不同的值

我一直在尝试根据时间从我的查询结果中删除重复项,但我需要考虑 3 个不同的时间,我不知道该怎么做。由于某些测试多次发生,part_id 上存在重复项,我只想从所有 3 个表中获得最后一次测试的结果。

我现在正在运行这个查询

select lb.request_ky,
lb.build_dm,
lb.part_id,
dv.date_test,
dv.result,
dw.date_test,
dw.result,
tt.date_test,
tt.result

From tableA lb,
tableB dv,
tableC dw,
tableD tt

Where lb.part_id = dv.part_id
And lb.part_id = dw.part_id
And lb.part_id = tt.part_id
Run Code Online (Sandbox Code Playgroud)

这个查询会给我部分 id 的重复项。我怎样才能从每个表中获取最新结果并将它们连接在一起?

oracle optimization

0
推荐指数
1
解决办法
5986
查看次数

如何提高 MySQL 的性能或查询执行时间?

这是我的查询:

SELECT          a.z_companyid_pk "z_companyid_pk"      ,
                a.company_name "Client"                ,
                a.display_name "Display_Name"          ,
                a.z_parentcompanyid_fk "Parent_Company",
                a.z_resellerid_fk "Reseller"           ,
                (SELECT company_name
                FROM    company_mst
                WHERE   z_companyid_pk= a.z_resellerid_fk
                )
                "Reseller_name",
                (SELECT IF(COUNT(*)>=1,"YES","NO")
                FROM    webprofile
                WHERE   z_boxid_fk IN
                        (SELECT z_boxid_pk
                        FROM    box_mst
                        WHERE   z_companyid_fk=a.z_companyid_pk
                        )
                )
                "V1_Website",
                (SELECT IF(COUNT(*)>=1,"YES","NO")
                FROM    webapp_mst
                WHERE   z_companyid_fk=a.z_companyid_pk
                )
                "V2_Website",
                (SELECT IF(COUNT(*)>0,"YES","NO")
                FROM    widget_mst
                WHERE   widget_status=1
                AND     type IN("templated-menu",
                                "menus")
                AND     z_companyid_fk=a.z_companyid_pk
                )
                "Widgets_with_my_menu",
                (SELECT IF(COUNT(imagehtml)>0,"YES","NO")
                FROM    image_mst
                WHERE   LENGTH(imagehtml)>0
                AND     z_companyid_fk   =a.z_companyid_pk
                )
                "HTML_menus",
                (SELECT         MAX(login_datetime)
                FROM            loginlog_mst a
                                LEFT …
Run Code Online (Sandbox Code Playgroud)

mysql performance optimization query-performance

0
推荐指数
1
解决办法
171
查看次数

哪些 SET 选项会影响计划重用以及如何在 T-SQL 中获取它们的值?

当存储过程在任何时候从管理工作室运行良好时,我正在对这种情况进行故障排除,但即使对于相同的参数,相同的存储过程在其中一个网络服务器中运行得非常糟糕。可能有一些原因导致这种情况,包括阻塞等。

我想排除使用不同 SET 选项创建 2 个不同计划的可能性,并且这些计划中至少有一个使用产生错误计划的参数组合进行了优化。

引用本杰明·内瓦雷斯:

“一般来说,查询优化是一个代价高昂的操作,为了避免这种优化成本,计划缓存会尽量将生成的执行计划保存在内存中,以便它们可以被重用。但是,如果一个新的连接运行相同的存储过程有不同的SET选项,它可能会生成一个新的计划……”

为了解决这个问题,我想要一个 T-SQL 查询,它会显示为会话设置的所有值。

这可能吗?

以下 SET 选项将影响执行计划的重用:

(他们中的一些)

DATEFORMAT
LANGUAGE
NUMERIC_ROUNDABORT
FORCEPLAN

performance sql-server optimization plan-cache sql-server-2014 query-performance

0
推荐指数
1
解决办法
239
查看次数

大数据库的高效价值更新

我有一个 8GB 大的表,有 20M 条记录。有一个名为 mth 的 int 字段。第 m 个字段以 YYYYMM 的形式存储日期信息,我想将第 m 个字段转换为连续整数。所以我使用一个公式从字段mth中获取年份和月份并计算月份顺序,具体来说,我使用以下代码:

create function mth_to_num(@month int)
returns int
as 
begin
   return(round(@month/100,0)*12+@month-100*round(@month/100,0))
end
Run Code Online (Sandbox Code Playgroud)

然后我用下面的代码来更新大表中的值

update full_orig_month_Q1_1999 
set mth_order = dbo.mth_to_num(period)
Go 
Run Code Online (Sandbox Code Playgroud)

但是,代码执行时间很长,大约 2-3 分钟。我的系统是带有 SQL Server 2016 的 Windows 10 64 位。有什么办法可以加快速度吗?

另一个问题是,执行上述查询后,我发现SQL server 在数据库中占用了多达8GB 的​​空间。需要那么多内存吗?我怎样才能释放它们?

提前感谢您的帮助!

杰森

performance sql-server optimization query-performance

0
推荐指数
1
解决办法
175
查看次数