想象一个视图,其中包含来自两个不同表的COALESCE两varchar列。
底层证券varchars在两个表中都有索引。
在 Postgres 11.6 中,根据结果过滤此视图COALESCE不使用索引,而是进行表扫描。
但是,如果我将列更改为text,在同一列上过滤完全相同的视图,则索引将按您的预期使用。
假设我有一个一些标识符随时间变化的测量值表。还有一个几乎相同的表,其中包含估计值:
CREATE TABLE measured (
id int,
ts timestamp,
identifier character varying,
measured_value int
);
CREATE INDEX ON measured(identifier);
CREATE TABLE estimated (
id int,
ts timestamp,
identifier character varying,
estimated_value int
);
CREATE INDEX ON estimated(identifier);
Run Code Online (Sandbox Code Playgroud)
每个表有 100 万行数据:
INSERT INTO measured
SELECT
generate_series(1, 1000000),
to_timestamp((random() * 100000)::int),
left(md5(random()::text), 2),
random() * 10;
INSERT INTO estimated
SELECT
generate_series(1, 1000000),
to_timestamp((random() * …Run Code Online (Sandbox Code Playgroud) postgresql varchar execution-plan index-tuning postgresql-performance
我有以下查询:
SELECT u.userId,
app.applicationId
FROM app.application AS app
INNER JOIN app.applicant AS ap
ON ap.applicantId = app.applicantId
INNER JOIN usr.[user] AS u
ON u.userId = ap.userId
LEFT JOIN msg.emailTemplateSent AS t
ON t.toUserId = u.userId
AND t.emailTemplateName = 'v4_before_sixWeek_latestFlight_reminder'
WHERE Convert(Date, GETUTCDATE()) =
DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
AND t.emailEventId IS NULL
ORDER BY app.applicationId ASC
Run Code Online (Sandbox Code Playgroud)
请再次注意where子句的第一行:
Convert(Date, GETUTCDATE()) = DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
Run Code Online (Sandbox Code Playgroud)
我可以以可以使用我的索引的方式更改此设置吗?索引实际上被使用了,但它是一个完整的扫描。
也可以在这里看到:
这是我的索引定义:
USE [APCore];
CREATE NONCLUSTERED INDEX i_flightDateLatest
ON [app].[application] ( flightDateLatest ASC )
INCLUDE ( [applicantId] , …Run Code Online (Sandbox Code Playgroud) index sql-server execution-plan sql-server-2016 query-performance
我们使用 Amazon RDS 实例
x86_64-pc-linux-gnu 上的 PostgreSQL 11.13,由 gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12) 编译,64 位
我有一个简单的经典每组前 1 名查询。我需要获取每个 的历史记录中的最新项目creativeScheduleId。
这是表和索引的定义:
CREATE TABLE IF NOT EXISTS public.creative_schedule_status_histories (
id serial PRIMARY KEY,
"creativeScheduleId" text NOT NULL,
-- other columns
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_creativescheduleid_id
ON public.creative_schedule_status_histories ("creativeScheduleId" ASC, id ASC);
Run Code Online (Sandbox Code Playgroud)
当引擎的查询排序时id ASC仅读取索引并且不执行任何额外的排序:
EXPLAIN (ANALYZE)
SELECT history.id, history."creativeScheduleId"
FROM (
SELECT cssh.id, cssh."creativeScheduleId"
, ROW_NUMBER() OVER (PARTITION BY cssh."creativeScheduleId"
ORDER BY cssh.id ASC) …Run Code Online (Sandbox Code Playgroud) postgresql index execution-plan window-functions greatest-n-per-group
我有一个大型分区表,用于存储帐户之间的货币交易。
CREATE TABLE "transactions" (
"from" BYTEA NOT NULL -- sender account
,"to" BYTEA NOT NULL -- receiver account
,"type" INTEGER NOT NULL -- type of transfer
,"ts" TIMESTAMP NOT NULL -- timestamp of transfer
) PARTITION BY RANGE ("ts");
Run Code Online (Sandbox Code Playgroud)
“transactions”在“ts”、“from”和“to”上有索引(“ts”用于排序)。
CREATE INDEX "transactions_ts_idx" ON "transactions" USING BTREE ("ts");
CREATE INDEX "transactions_from_idx" ON "transactions" USING BTREE ("from", "ts");
CREATE INDEX "transactions_to_idx" ON "transactions" USING BTREE ("to", "ts");
Run Code Online (Sandbox Code Playgroud)
我想查询涉及给定帐户或没有帐户的所有交易,例如:
-- given an account <account>
SELECT * FROM "transactions"
WHERE "from" = …Run Code Online (Sandbox Code Playgroud) postgresql index execution-plan index-tuning query-performance
我有两个简单的查询:
SELECT TOP(20) * FROM Clients ORDER BY City
Run Code Online (Sandbox Code Playgroud)
SELECT TOP(20) Id, Name, City FROM Clients ORDER BY City
Run Code Online (Sandbox Code Playgroud)
在第一种情况下我得到这样的结果
| ID | 姓名 | 城市 | 更多专栏 |
|---|---|---|---|
| 6 | 6人 | 无效的 | ... |
| 2 | 2人 | 无效的 | ... |
| 3 | 3号人 | 无效的 | ... |
在第二种情况下,我得到这样的结果 在第一种情况下,我得到这样的结果
| ID | 姓名 | 城市 |
|---|---|---|
| 2 | 2人 | 无效的 |
| 3 | 3号人 | 无效的 |
| 6 | 6人 | 无效的 |
请注意,顺序不同。当然,我理解,因为 City 对于这三个人来说是 NULL,所以不一定能保证唯一的顺序。
第二个查询没有:
在阅读有关并行查询处理的文档后,它特别提到某些构造会抑制并行性,例如 TOP 运算符。
除了并行性之外,唯一显着的区别是并行计划的 Top N Sort 节点的估计 I/O 成本为 16,而非并行查询计划的 Top N Sort 节点仅具有估计 I/O 成本成本0.01
所以我的问题是:为什么当我使用 TOP 运算符时它仍然会使用并行性,即使微软声明它应该抑制该机制?
给出以下两个表:
CREATE TABLE SalesLedger (
Id int PRIMARY KEY IDENTITY,
Date date NOT NULL,
Total decimal(38,18),
INDEX IX (Date, Total)
);
CREATE TABLE Purchases (
Id int PRIMARY KEY IDENTITY,
Date date NOT NULL,
Total decimal(38,18),
INDEX IX (Date, Total)
);
Run Code Online (Sandbox Code Playgroud)
以及下面的视图
CREATE VIEW ViewMetrics
AS
Select
Date,
'Sale' as Metric,
Total as Value
From SalesLedger
UNION ALL
Select
Date,
'Purchase' as Metric,
Total as Value
From Purchases;
Run Code Online (Sandbox Code Playgroud)
以下查询使用一Concatenation Sort对:
Select SUM(Value) as Sales, Date
from ViewMetrics …Run Code Online (Sandbox Code Playgroud) 我从播客中听说没有 ORM 可以很好地解决执行计划重用问题。它会导致执行计划缓存增加,从而影响性能。
服务器 A 和服务器 B 具有相同的硬件和实例配置(A 是生产,B 是 QA)。B 的数据库是从一周前 A 的备份中恢复的。开发团队向我提供了这个查询。
SELECT
c.Start
,c.[End]
,c.Word
,doc.UniqueDocumentNumber
,doc.EID
,c.CUI
,c.Concept
,a.OID
,doc.DocumentTypeName
,doc.ActivityDtTm
,CAST(doc.DocumentTypeId AS INT) AS MedCode
,CASE WHEN c.[Count] = 0 THEN CAST(0.00 AS REAL)
ELSE CAST(LOG(c.TotalCount / c.[Count]) AS REAL) END AS 'idf'
,c.[Count]
,c.TotalCount
FROM ECHO..AEID201 a
INNER JOIN ALPHA..XADocuments doc (NOLOCK) ON a.EID = doc.EID
CROSS APPLY (SELECT t.start,t.[end],t.word,t.cui,t.eid,
t.UniqueDocumentNumber,cu.[Count],cc.TotalCount,core.Concept
FROM HOTEL.dbo.Htf_Index AS t
INNER JOIN HOTEL..Doc_CUI_Counter AS cu ON cu.CUI=t.CUI AND cu.DocumentTypeID=t.DocumentTypeID
INNER JOIN HOTEL..Doc_Counter …Run Code Online (Sandbox Code Playgroud) execution-plan sql-server-2008-r2 subquery functions cross-apply
在以下查询中,我必须为每个客户计算交易。但是,我必须从结果集中完全排除交易时间超过一年的客户。
查询优化器不应该足够聪明,只为每个客户评估一次存在吗?
--Count transactions on customers that are less than 1 year old
SELECT t1.CUSTID, COUNT(*)
FROM CUST_TRX t1
WHERE NOT EXISTS (
SELECT FIRST 1 1
FROM CUST_TRX t2
WHERE
t2.CUSTID = t1.CUSTID AND
t2.DATED < CURRENT_DATE - 365
GROUP BY t2.CUSTID
)
GROUP BY t1.CUSTID
Run Code Online (Sandbox Code Playgroud)
我的查询计划中没有自然。此查询的执行就像数据库为每个事务运行存在子句,而不是为每个客户运行它。如果我删除GROUP BY子查询中的,则性能相同。
有没有更好的方法来做到这一点,以便我可以从数据库中获得更好的性能?SELECT如果可能的话,希望一个简单的查询能够避免 CTE(这会带来其他挑战)。
由于其他GROUP BY条件(此处未显示),我无法简单地检查MIN(DATED),我确实需要执行另一个查询。
performance execution-plan subquery firebird query-performance
我刚刚开始学习优化我的查询并分析他们的查询计划。我认为这个查询会生成非聚集索引查找 + 键查找。
SELECT ct.*
FROM Person.ContactType AS ct
WHERE ct.Name LIKE 'Own%';
Run Code Online (Sandbox Code Playgroud)
相反,它使用聚集索引扫描。我不知道为什么。
我正在 SQL Server 2012 Express 上使用 AdventureWorks2012 数据库。ContactTypeId 列上有聚集索引,Name 列上有非聚集索引。第三列 (ModifiedDate) 不属于任何索引。该表仅包含 20 行。
我怀疑查询优化器决定进行聚集索引扫描,因为表只有 20 行,也许扫描索引然后进行键查找更快。
sql-server execution-plan sql-server-2012 sql-server-express
execution-plan ×10
sql-server ×5
index ×3
postgresql ×3
index-tuning ×2
subquery ×2
cross-apply ×1
firebird ×1
functions ×1
optimization ×1
orm ×1
parallelism ×1
performance ×1
varchar ×1