我有一个INSERT INTO... SELECT ... FROMSQL 语句,从命令行 shell 执行时运行速度可以接受SQLite's。
但是,如果我使用 Perl 执行相同的语句(复制/粘贴)DBI::SQLite,则该语句会变慢。
原因一定是执行计划:当我让语句从 shell 和内部解释时DBI::SQLite,它们是不同的:快速版本使用最佳索引和表顺序,慢速版本选择以小于最佳方式。
所以,我有两个问题。
我有一个很长的查询,我将在这里总结并粘贴在底部:
select * from
a
left join b t1 on a.x = b.x
left join b t2 on a.y = b.x
left join b t3 on a.z = b.x
left join c on a.1 = c.1 and a.2 = c.2 and a.3 = c.3 --call this predicate 1
where c.z is null
Run Code Online (Sandbox Code Playgroud)
a 和 c 有主键 1,2,3 非聚集 ax y 或 z 可以为 null 您将在下面链接的内容中看到 a 是 40k 行,c 是 500k 行,b 是 7k 行。此查询需要 10 分钟。直接用excel手工做会更快。即使我运行了真空完整分析并且它有不应该的嵌套循环,我的行计数估计都是错误的
这是完整的 https://explain.depesz.com/s/w2uN
当我删除谓词 …
我正在 Postgres 中使用 HackerNews 数据集。大约有 1700 万行,其中大约 1450 万行是评论,大约 250 万行是故事。有一个名为“rbanffy”的非常活跃的用户,他提交了 25,000 条文章,大约有相等的分裂故事/评论。“by”和“type”都有单独的索引。
我有一个疑问:
SELECT *
FROM "hn_items"
WHERE by = 'rbanffy'
and type = 'story'
ORDER BY id DESC
LIMIT 20 OFFSET 0
Run Code Online (Sandbox Code Playgroud)
运行速度很快(它使用“by”索引)。如果我将类型更改为“评论”,那么速度会非常慢。从解释来看,它不使用任何索引并进行扫描。
Limit (cost=0.56..56948.32 rows=20 width=1937)
-> Index Scan using hn_items_pkey on hn_items (cost=0.56..45823012.32 rows=16093 width=1937)
Filter: (((by)::text = 'rbanffy'::text) AND ((type)::text = 'comment'::text))
Run Code Online (Sandbox Code Playgroud)
如果我将查询更改为 has type||''='comment',那么它将使用“by”索引并快速执行。
为什么会发生这种情况?我从/sf/answers/21687011/了解到,必须进行这样的黑客攻击意味着出现了问题。但我不知道是什么。
编辑:
这是 type='story' 的解释
Limit (cost=72553.07..72553.12 rows=20 width=1255)
-> Sort (cost=72553.07..72561.25 rows=3271 width=1255)
Sort Key: id …Run Code Online (Sandbox Code Playgroud) postgresql indexing sql-execution-plan postgresql-performance
说我有这个查询:
EXPLAIN SELECT *
FROM (
SELECT "A" as a, i.n FROM (SELECT 1 AS n) AS i
UNION ALL SELECT "B" as a, i.n FROM (SELECT 1 AS n) AS i) AS t
WHERE a = "B";
Run Code Online (Sandbox Code Playgroud)
MySQL 说
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> \N ref <auto_key0> <auto_key0> 6 const 1 100.00 \N
2 DERIVED <derived3> \N system \N \N \N \N 1 100.00 \N
3 DERIVED \N \N …Run Code Online (Sandbox Code Playgroud) 在 SSMS 中,当我启用实时查询统计信息时,我可以在窗口左下角看到执行百分比。

我想在 Windows 窗体上向最终用户显示这个递增的百分比。到目前为止,我尝试在 Visual Studio 上使用进度条来实现此目的,但事实证明,直到我使用数据表为止,这是不可能的。

忘记进度条,即使我可以在标签上以文本格式显示增量百分比 - 就像在 SSMS 中一样,它会完成这项工作。
任何用 C# 实现代码的建议都会有帮助。
在我的 Postgres 服务器上,我使用onauto_explain模块来log_nested_statements记录 PL/pgSQL 函数中的其他函数调用。
594 session_preload_libraries = 'auto_explain'
595
596 auto_explain.log_min_duration = 0
597 auto_explain.log_nested_statements = true
598 auto_explain.sample_rate = 1.0
Run Code Online (Sandbox Code Playgroud)
我有一个玩具 PL/pgSQL 函数baz(count int):
Schema | public
Name | baz
Result data type | text
Argument data types | count integer
Type | normal
Volatility | volatile
Parallel | unsafe
Owner | aerust
Security | invoker
Access privileges |
Language | plpgsql
Source code | +
| DECLARE +
| i int …Run Code Online (Sandbox Code Playgroud) 我正在查看实际的执行计划
SELECT *
FROM dbo.Parcels pr
WHERE (pr.Barcode = 'AB123456789DE')
Run Code Online (Sandbox Code Playgroud)
实际的执行计划包含一个运算符(索引查找非聚集),其下方有“1 of 16 (6%)”
1 表示返回的 1 行。
但16岁?它不能是行,因为该表中有 700k 行。是页数吗?
我看这里的文档。
我在索引查找下没有找到任何有用的东西。
我遇到了一个"太长"的查询.该查询在10个左右的表之间有50多个左连接.为了简要概述数据库模型,连接的表是存储特定数据类型数据的表(例如:date_fields,integer_fields,text_fields等),每个表都有一个值列,一个"datafield"id,和票证ID.查询是基于"票证"及其"数据字段"之间的关联表以编程方式构建的.
join语句如下所示:
...FROM tickets t
LEFT JOIN ticket_text_fields t001 ON(t.id=t001.ticket_id AND t001.textfield_id=7)
...
LEFT JOIN ticket_date_fields t056 ON(t.id=t056.ticket_id AND t056.datafield_id=434)
Run Code Online (Sandbox Code Playgroud)
在查询上使用说明时显示以下内容:
1 SIMPLE t ref idx_dataset_id idx_dataset_id 5 const 2871 Using where; Using temporary; Using filesort
1 SIMPLE t001 ref idx_ticket_id,idx_datafield_id idx_ticket_id 5 t.id 5
...
1 SIMPLE t056 ref idx_ticket_id,idx_datafield_id idx_ticket_id 5 t.id 8
Run Code Online (Sandbox Code Playgroud)
我可以采取什么方向来调整此查询?所有索引似乎都已到位.也许应该减少t表(票)行号(2871).有多少左连接太多了?数据域表是否应仅连接一次,然后查询每个所需的数据?
我想知道你们是否可以帮我解决我最近在SQL Server上遇到的一个奇怪问题.
我有一个存储过程(让我们调用SPold)相当大,有很多计算(不能在应用程序中执行此操作,因为大约6000个用户的信息需要一次性返回(我将此值减少到1000)姓)).存储过程通常在几秒钟内执行,并且每隔几分钟调用一次.
现在今天早上,存储过程突然执行了4-10倍,导致了一些超时.我发现通过使用新名称(SPnew)执行该过程的副本并执行,我将再次获得快速执行时间.这告诉我执行计划是原始的问题SPold,所以我决定通过重新编译来执行它.这样可以更快地返回结果(虽然没有那么快SPnew),但用户的后续调用SPold再次变慢.这就好像没有保留新计划.
我所做的就是解决这个问题放Exec SPnew成SPold,现在调用SPold正在迅速再次返回.
有谁知道这里发生了什么?那一夜更新的唯一的事就是统计数据,但我认为这应该不会影响这两个SPold和SPnew.
sql-server stored-procedures sql-server-2005 sql-execution-plan
有没有办法像Java调试一样查看mysql / oracle查询执行计划。我想知道mysql / oracle如何执行我们的查询以及执行过程涉及哪些步骤。
postgresql ×3
sql-server ×3
mysql ×2
sql ×2
c# ×1
dbi ×1
explain ×1
indexing ×1
left-join ×1
logging ×1
optimization ×1
perl ×1
sqlite ×1
ssms ×1