注意:原始问题没有实际意义,但扫描到底部是否有相关内容.
我有一个我想要优化的查询,看起来像这样:
select cols from tbl where col = "some run time value" limit 1;
Run Code Online (Sandbox Code Playgroud)
我想知道正在使用什么键,但无论我传递什么来解释,它都能够将where子句优化为什么("Impossible WHERE注意到......"),因为我给它一个常量.
编辑:EXPLAIN
似乎是给我一个由常量值产生的查询计划.由于查询是存储过程的一部分(并且sproc中的IIRC查询计划在调用之前生成),这对我没有好处,因为该值不是常量.我想要的是找出优化器在不知道实际值是什么时将生成什么查询计划.
我错过了吗?
编辑2:在其他地方询问,似乎MySQL总是重新生成查询计划,除非你不遗余力地重新使用它们.即使在存储过程中.从这看起来我的问题似乎没有实际意义.
然而,这并没有使我真正想知道的事情没有实际意义: 如何优化包含在任何特定查询中不变的值的查询,但我,程序员,事先不知道将使用什么值?- 例如,假设我的客户端代码正在生成一个带有其where
子句中的数字的查询.有时这个数字会导致一个不可能的where子句,否则它将不会.如何使用explain来检查查询的优化程度?
我现在看到的最好的方法是EXPLAIN
在其上运行存在/不存在的情况的完整矩阵.真的,这不是一个非常好的解决方案,因为手动操作既困难又容易出错.
当我尝试做类似的事情
SELECT Max(ObjectId) FROM Objects;
Run Code Online (Sandbox Code Playgroud)
我在解释计划中看到这是通过排序来执行的.现在,排序(我认为需要复杂性的东西O(nlogn)
)必须比扫描每一行并记住最大值(可以在其中完成O(n)
)花费更多.
我在这里错过了什么吗?oracle是真的执行排序还是解释计划只是使用描述"sort"来描述ObjectId列中所有值的简单扫描?如果oracle确实执行了"真正的排序",那么我有理由这样做吗?
提前致谢!
我在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)
这样行得通,但是我得到了多余的结果。最终,我想获得索引查找和扫描的结果,但是现在我还看到了行,其中索引被修改了(例如,针对常规表更新的执行计划,因为索引也在被更新)。
这是一些简化的示例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) 我有两张桌子
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) 我正在尝试加快我的存储过程,所以我使用下面的统计信息以两种格式测试我的存储过程
方法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
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。为什么会发生这种情况?
我的函数只有一个参数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 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
我尝试选择一个包含 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)
请注意,我在 …
我正在使用 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-server ×5
sql ×4
performance ×2
postgresql ×2
indexing ×1
join ×1
max ×1
mysql ×1
nested-loops ×1
optimization ×1
oracle ×1
pgadmin ×1
sqlite ×1
t-sql ×1
temp-tables ×1
where-clause ×1
xml ×1