标签: sql-execution-plan

如何使用常量优化MySQL的查询?

注意:原始问题没有实际意义,但扫描到底部是否有相关内容.

我有一个我想要优化的查询,看起来像这样:

select cols from tbl where col = "some run time value" limit 1;
Run Code Online (Sandbox Code Playgroud)

我想知道正在使用什么键,但无论我传递什么来解释,它都能够将where子句优化为什么("Impossible WHERE注意到......"),因为我给它一个常量.

  • 有没有办法告诉mysql不要在解释中做不断的优化?
  • 我错过了什么吗?
  • 有没有更好的方法来获取我需要的信息?

编辑:EXPLAIN似乎是给我一个由常量值产生的查询计划.由于查询是存储过程的一部分(并且sproc中的IIRC查询计划在调用之前生成),这对我没有好处,因为该值不是常量.我想要的是找出优化器在不知道实际值是什么时将生成什么查询计划.

我错过了吗?

编辑2:在其他地方询问,似乎MySQL总是重新生成查询计划,除非你不遗余力地重新使用它们.即使在存储过程中.从这看起来我的问题似乎没有实际意义.

然而,这并没有使我真正想知道的事情没有实际意义: 如何优化包含在任何特定查询中不变的值的查询,但我,程序员,事先不知道将使用什么值?- 例如,假设我的客户端代码正在生成一个带有其where子句中的数字的查询.有时这个数字会导致一个不可能的where子句,否则它将不会.如何使用explain来检查查询的优化程度?

我现在看到的最好的方法是EXPLAIN在其上运行存在/不存在的情况的完整矩阵.真的,这不是一个非常好的解决方案,因为手动操作既困难又容易出错.

mysql optimization sql-execution-plan

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

为什么Max()在解释计划中创建订单?

当我尝试做类似的事情

SELECT Max(ObjectId) FROM Objects;
Run Code Online (Sandbox Code Playgroud)

我在解释计划中看到这是通过排序来执行的.现在,排序(我认为需要复杂性的东西O(nlogn))必须比扫描每一行并记住最大值(可以在其中完成O(n))花费更多.

我在这里错过了什么吗?oracle是真的执行排序还是解释计划只是使用描述"sort"来描述ObjectId列中所有值的简单扫描?如果oracle确实执行了"真正的排序",那么我有理由这样做吗?

提前致谢!

oracle max sql-execution-plan

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

如何使用TSQL在WHERE子句中过滤XML执行计划数据

我在SO上看到了几个响应,其中TSQL语句使用XML数据类型的.value或.exist方法(此处此处)对XML数据进行过滤。尽管我不熟悉这些方法的构造/语法,但我有一个更深的问题。

我试图查询一些缓存的执行计划数据,并在数据中搜索特定索引的引用,问题是我不知道XML的位置。现在,我将XML转换为NVARCHAR并仅使用LIKE(请参阅查询的最后一行):

  DECLARE @IndexName NVARCHAR(100) = 'MyIndex'

    SELECT  OBJECT_NAME(objectid) AS procname, usecounts, query_plan
    FROM    sys.dm_exec_cached_plans cp
    CROSS   APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
    WHERE   objtype = 'Proc'
    AND     CAST(query_plan AS NVARCHAR(MAX)) LIKE '%' + @IndexName + '%'
Run Code Online (Sandbox Code Playgroud)

这样行得通,但是我得到了多余的结果。最终,我想获得索引查找和扫描的结果,但是现在我还看到了行,其中索引被修改了(例如,针对常规表更新的执行计划,因为索引也在被更新)。

  1. 如何改写查询的最后一行以使用某种通配符XML语法(并避免使用CASTing)?
  2. 如何优化查询以仅返回父节点为“ IndexScan”的那些项目
  3. 如何优化查询以仅返回其第一个找到的祖先“ RelOp”具有名为“ PhysicialOp”且值为“ Index Seek”的项?

这是一些简化的示例XML:

<RelOp NodeId="13" PhysicalOp="Index Seek" LogicalOp="Index Seek">
    <OutputList>
        <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Employees]" Column="EmployeeID" />
    </OutputList>
    <IndexScan Ordered="1" ScanDirection="FORWARD">
        <DefinedValues>
            <DefinedValue>
                <ColumnReference Database="[MyDB]" Table="[Employees]" Column="EmployeeID" />
            </DefinedValue>
        </DefinedValues>
        <Object Database="[MyDB]" Schema="[dbo]" Table="[Employees]" Index="[MyIndex]" /> …
Run Code Online (Sandbox Code Playgroud)

xml t-sql sql-server sql-execution-plan

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

如果根据EXPLAIN QUERY PLAN,为什么SQL查询比另一个慢?它应该相反?

我有两张桌子

CREATE TABLE Categories (
   Category INTEGER,
   Id INTEGER,
   FOREIGN KEY (Category) REFERENCES CategoriesInfo(Category)
)
CREATE TABLE 'CategoriesInfo' (
   'Category' INTEGER PRIMARY KEY NOT NULL,
   'Name' TEXT
)
Run Code Online (Sandbox Code Playgroud)

有索引

CREATE UNIQUE INDEX idxCategory ON Categories (Category, Id)
Run Code Online (Sandbox Code Playgroud)

如果我跑

EXPLAIN QUERY PLAN
SELECT CategoriesInfo.Category, Name
FROM Categories, CategoriesInfo
Where Categories.Category=CategoriesInfo.Category AND Id=:id
ORDER BY Name
Run Code Online (Sandbox Code Playgroud)

它说

Array
(
    [0] => Array
        (
            [selectid] => 0
            [order] => 0
            [from] => 1
            [detail] => SCAN TABLE CategoriesInfo (~1475 rows)
        )

    [1] => …
Run Code Online (Sandbox Code Playgroud)

sql sqlite performance sql-execution-plan

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

内连接vs where子句子查询sql server

我正在尝试加快我的存储过程,所以我使用下面的统计信息以两种格式测试我的存储过程

方法1:使用join

set statistics io on 

select top 2000   
    p.Vehicleno, 
    dbo.GetVehicleStatusIcon1(p.Direction, StatusCode, 0) as 'Status',
    location,
    Convert(varchar(13), p.TrackTime, 102) + ' ' + Convert(varchar(13), p.TrackTime, 108) AS 'TrackTime',
    p.Speed, p.Ignition
from 
    pollingdata p 
inner join 
    assignvehicletouser asn on asn.vehicleno = p.vehicleno
where 
    asn.empid = 1
Run Code Online (Sandbox Code Playgroud)

我得到统计结果为

Table 'Worktable'. Scan count 943, logical reads 7671, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AssignVehicleToUser'. Scan count 1, logical reads 41, …
Run Code Online (Sandbox Code Playgroud)

sql-server join where-clause logical-reads sql-execution-plan

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

什么是执行计划中的并行性(分发流)

Parallelism(Distribute Streams)中的操作是什么Execution plan?为什么它增加了上一个操作的行数。

询问 :

SELECT TOP 5000 MM.MEMBER_ID,
                MM.MEMBER_NO,
                MM.MEMBER_NAME,
                MM.TRADE_CLASS,
                MT.DESCRIPTION,
                MS.DESCRIPTION,
                MAI.ADDRESS_1,
                MAI.ADDRESS_2,
                MAI.CITY,
                MAI.STATE,
                MAI.ZIP
FROM   MEMBER_MASTER MM
       INNER JOIN MEMBER_TYPE MT
               ON MT.CODE = MM.MEMBER_TYPE
       INNER JOIN MEMBER_STATUS MS
               ON MS.CODE = MM.MEMBER_STATUS
       INNER JOIN MEMBER_ADDRESS_INFO MAI
               ON MM.MEMBER_ID = MAI.MEMBER_ID
WHERE  MAI.PRIMARY_ADDRESS_FLAG = 'YES'
Run Code Online (Sandbox Code Playgroud)

执行计划:

在此输入图像描述

从上面的执行计划可以清楚地看到行数从39,771增加到1,272,672。为什么会发生这种情况?

sql sql-server sql-execution-plan

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

如何使用参数/变量并一起解释

我的函数只有一个参数carAzimuth

CREATE OR REPLACE FUNCTION map.get_near_link(x numeric, y numeric, carAzimuth numeric)
Run Code Online (Sandbox Code Playgroud)

里面我有一些计算和这个查询

SELECT *
FROM map.vzla_seg S
WHERE
    S.azimuth > carAzimuth - 30  and   
    S.azimuth < carAzimuth + 30  or
    S.azimuth < carAzimuth - 330 or 
    S.azimuth > carAzimuth + 330;
Run Code Online (Sandbox Code Playgroud)

我想分析查询性能。所以我必须将变量替换为常量。并且工作正常,并向EXPLAIN PLAN我展示正在使用正确的索引。

EXPLAIN ANALYZE    
 SELECT *
 FROM map.vzla_seg S
 WHERE
    S.azimuth > 345 - 30  and   
    S.azimuth < 345 + 30  or
    S.azimuth < 345 - 330 or 
    S.azimuth > 345 + 330;
Run Code Online (Sandbox Code Playgroud)

但如果想测试不同的值,改变每个变量是很麻烦的。那么如果你尝试

EXPLAIN …
Run Code Online (Sandbox Code Playgroud)

sql postgresql performance sql-execution-plan pgadmin

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

SQL Server使用嵌套循环,因为估计的行数很差

我使用SQL Server 2008 R2.我创建了一个临时表,然后用1000行填充临时表.

Create Table #Temp
(
  ID Int,
  res INT
)

Insert Into #Temp 
VALUES (10004, 2246), (10005, 2246), (10006, 2246), (10007, 2246),
       (10008, 2246), (10009, 2246), (10010, 2246), (10011, 2246),
       (10013, 2246), (10014, 2246), (10015, 2246), (10016, 2246),
       (10017, 2246), (10018, 2246), (10019, 2246), (10020, 2246),
       (10021, 2246), ................ 
Run Code Online (Sandbox Code Playgroud)

我有另一个名为的表Item.它有大约30000条记录.

我有一个INNER JOIN介于Item我和临时表之间.

Select 
    * 
From 
    Inventory.Item 
Inner Join
    #Temp On (#Temp.ID = item.MasterID And MRes = ExRestaurantID)
Run Code Online (Sandbox Code Playgroud)

正如您在下面的三张图片中看到的,SQL Server已经为我的查询创建了一个执行计划,但在他的计划中,它估计我的Item表只有一行,因此它使用了嵌套循环连接. …

sql-server temp-tables nested-loops sql-server-2008-r2 sql-execution-plan

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

在sql server中选择1700万条记录非常慢

我尝试选择一个包含 1700 万条记录的表。大约需要10分钟。在这里您可以看到实时执行计划。

在此输入图像描述

这是我的表结构:

CREATE TABLE [bas].[GatewayReceipt](
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [CustomerId] [INT] NULL,
    [UserId] [INT] NOT NULL,
    [RefNumber] [NVARCHAR](200) NULL,
    [ResNumber] [NVARCHAR](200) NULL,
    [Price] [DECIMAL](18, 5) NOT NULL,
    [GatewayChannelId] [INT] NOT NULL,
    [StatusId] [INT] NOT NULL,
    [EntryDate] [DATETIME] NOT NULL,
    [ModifyDate] [DATETIME] NULL,
    [RowVersion] [TIMESTAMP] NOT NULL,
 CONSTRAINT [PK_Bas_GatewayReceipt] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [FG_ATS]
) ON [FG_ATS]
GO
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

请注意,我在 …

sql-server indexing sql-execution-plan

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

为什么 LIMIT 2 查询可以工作,但 LIMIT 1 总是超时?

我正在使用 NEAR 协议的公共 Postgres 数据库:https://github.com/near/near-indexer-for-explorer#shared-public-access

postgres://public_readonly:nearprotocol@mainnet.db.explorer.indexer.near.dev/mainnet_explorer

SELECT "public"."receipts"."receipt_id",
    "public"."receipts"."included_in_block_hash",
    "public"."receipts"."included_in_chunk_hash",
    "public"."receipts"."index_in_chunk",
    "public"."receipts"."included_in_block_timestamp",
    "public"."receipts"."predecessor_account_id",
    "public"."receipts"."receiver_account_id",
    "public"."receipts"."receipt_kind",
    "public"."receipts"."originated_from_transaction_hash"
FROM "public"."receipts"
WHERE ("public"."receipts"."receipt_id") IN
        (SELECT "t0"."receipt_id"
            FROM "public"."receipts" AS "t0"
            INNER JOIN "public"."action_receipts" AS "j0" ON ("j0"."receipt_id") = ("t0"."receipt_id")
            WHERE ("j0"."signer_account_id" = 'ryancwalsh.near'
                                        AND "t0"."receipt_id" IS NOT NULL))
ORDER BY "public"."receipts"."included_in_block_timestamp" DESC
LIMIT 1
OFFSET 0
Run Code Online (Sandbox Code Playgroud)

总是会导致:

ERROR:  canceling statement due to statement timeout
SQL state: 57014
Run Code Online (Sandbox Code Playgroud)

但如果我将其更改为 LIMIT 2,则查询运行时间不到 1 秒。

怎么会是这样呢?这是否意味着数据库没有设置好?或者我做错了什么?

PS 这里的查询是通过 Prisma 生成的。findFirst总是超时,所以我想我可能需要将其更改findMany为解决方法。

sql postgresql sql-execution-plan postgresql-performance

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