标签: sql-execution-plan

Postgres EXPLAIN ANALYZE 比正常运行查询快得多

我正在尝试优化 PostgreSQL 8.4 查询。在大大简化了原始查询之后,试图找出是什么让它选择了一个糟糕的查询计划,我发现在 EXPLAIN ANALYZE 下运行查询只需要 0.5 秒,而运行它通常需要 2.8 秒。那么很明显,EXPLAIN ANALYZE 显示给我的不是它通常所做的,所以它显示给我的都是无用的,不是吗?这里发生了什么,我如何看到它真正在做什么?

sql postgresql sql-execution-plan

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

Hive 解释计划理解

有没有什么合适的资源可以让我们完全理解hive生成的解释计划?我曾尝试在 wiki 中搜索它,但找不到完整的指南来理解它。这是 wiki,它简要解释了解释计划的工作原理。但我需要有关如何推断解释计划的更多信息。 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain

hadoop hive explain sql-execution-plan hiveql

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

我如何知道查询中是否使用了任何索引?PostgreSQL 11?

我有点困惑,需要一些建议。我用PostgreSQL 11数据库。我有这么简单的sql语句:

SELECT DISTINCT "CITY", "AREA", "REGION"
    FROM youtube
WHERE
    "CITY" IS NOT NULL
AND
    "AREA" IS NOT NULL
AND
    "REGION" IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

youtube我在 sql 语句中使用的表有 2500 万条记录。我认为这就是为什么查询需要 15-17 秒才能完成。对于我使用该查询的 Web 项目,它太长了。我正在尝试加快请求。

我为 youtube 表创建了这样的索引:

CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");
Run Code Online (Sandbox Code Playgroud)

在这一步之后,我再次运行查询,但需要相同的时间才能完成。似乎查询不使用索引。我如何知道查询中是否使用了任何索引?

解释分析返回: 在此处输入图片说明

sql postgresql sql-execution-plan postgresql-performance

6
推荐指数
2
解决办法
8799
查看次数

查询必须等待 XX 秒才能获得 MemoryGrant

我收到警告消息

查询在执行期间必须等待 xx 秒以获得 MemoryGrant

从 SQL 执行计划。我可以知道导致此警告消息出现的原因/可能性是什么吗?

是由于系统内存泄漏还是等待其他待处理的 SQL 查询完成?

我从 SQL 配置文件中提取了查询,该配置文件是从实体框架(Linq)生成并在 SSMS 2019 中运行的。

在此输入图像描述

sql-server sql-execution-plan

6
推荐指数
0
解决办法
2853
查看次数

MySQL 优化器 - 成本规划器不知道 DuplicateWeedout 策略何时创建磁盘表

这是我的示例查询

Select table1.id 
from table1 
where table.id in (select table2.id 
                    from table2 
                    where table2.id in (select table3.id 
                                        from table3)
                    ) 
order by table1.id  
limit 100
Run Code Online (Sandbox Code Playgroud)

在检查上述查询的优化器跟踪时。优化器跟踪成本

  1. DUPLICATE-WEEDOUT 策略 - 成本:1.08e7
  2. FIRST MATCH 策略 - 成本:1.85e7

由于 DUPLICATE-WEEDOUT 成本较低,mysql 对上述查询采取了 DUPLICATE-WEEDOUT 策略。

join_optimization 部分似乎一切都很好。但最后,在检查了 join_execution 部分之后。DUPLICATE-WEEDOUT 通常会创建临时表。但是这里由于堆大小不足以容纳临时表,它继续创建磁盘临时表(converting_tmp_table_to_ondisk)。

由于磁盘临时表,我的查询执行变慢了。


那么这里发生了什么?

优化器跟踪不计算连接优化部分本身的磁盘表成本。如果计算磁盘表成本,它将高于第一次匹配。那么 final_semijoin_strategy 将是 FIRST-MAT​​CH 策略,这样我的查询会更快。

MYSQL 有什么方法可以计算连接优化部分本身的磁盘表成本或针对此特定问题的任何其他解决方法吗?

MYSQ-5.7, INNODB


注意:这是一个非常动态的查询,其中多个条件将根据查询中的请求添加。所以我已经以所有可能的方式优化了查询。最后还是解决了这个磁盘表成本问题。请避免优化查询(如更改查询结构、强制优先匹配策略)。并且为了增加堆大小(我不太确定,在不同的论坛中很多人说它可能会在其他查询中带来不同的问题)

mysql sql innodb sql-execution-plan

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

重新启用外键约束后执行计划奇怪

我有一个奇怪的问题,在设置nocheck外部约束并重新启用它之后,

我得到了与nocheckon 一起使用的同样过时的执行计划.

为什么SQL服务器会生成执行计划,就好像外部约束FKBtoA被禁用,即使再次使用以下语句添加检查?

alter table B check constraint FKBtoA
Run Code Online (Sandbox Code Playgroud)

[UPDATE1]
到目前为止,删除外部约束并读取它有效.

alter table B drop constraint FKBtoA
alter table B add constraint FKBtoA foreign key (AID) references A(ID)
Run Code Online (Sandbox Code Playgroud)

但对于真正的大桌子来说,这似乎是一种矫枉过正 - 有更好的方法吗?

[回答]

我不得不WITH CHECK在下面添加alter语句来获取旧的执行计划

alter table B WITH CHECK add constraint FKBtoA foreign key (AID) references A(ID)
Run Code Online (Sandbox Code Playgroud)

这是一个完整的SQL语句

create table A ( ID int identity primary key )
create table B ( 
    ID int identity primary key,
    AID int not null …
Run Code Online (Sandbox Code Playgroud)

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

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

mysql多列索引无法正常工作(如预期的那样)?

我有一张这样的桌子

CREATE TABLE IF NOT EXISTS `tbl_folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `owner_userid` int(11) NOT NULL,
  `name` varchar(63) NOT NULL,
  `description` text NOT NULL,
  `visibility` tinyint(4) NOT NULL DEFAULT '2',
  `num_items` int(11) NOT NULL DEFAULT '0',
  `num_subscribers` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `owner_userid` (`owner_userid`),
  KEY `vis_sub_item` (`visibility`,`num_subscribers`,`num_items`)
) ENGINE=InnoDB
Run Code Online (Sandbox Code Playgroud)

因为我有一个可见性索引,num_subscribers和num_items,我希望只需要查看前15行,而EXPLAIN说55856行.任何的想法?谢谢

EXPLAIN SELECT t.id, name, description, owner_userid, num_items, num_subscribers
FROM  `tbl_folder`  `t` 
WHERE visibility =2
ORDER BY  `t`.`num_subscribers` DESC ,  `t`.`num_items` DESC 
LIMIT 15

id select_type …
Run Code Online (Sandbox Code Playgroud)

mysql indexing sql-order-by compound-index sql-execution-plan

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

为什么SQL Server在"select*"操作中使用非聚集索引而不是聚簇PK?

我有一个非常简单的桌子,为人们存储标题("先生","太太"等).这是我正在做的简要版本(在这个例子中使用临时表,但结果是相同的):

create table #titles (
    t_id    tinyint     not null    identity(1, 1),
    title   varchar(20) not null,

    constraint pk_titles primary key clustered (t_id),
    constraint ux_titles unique nonclustered (title)
)
go

insert #titles values ('Mr')
insert #titles values ('Mrs')
insert #titles values ('Miss')

select * from #titles

drop table #titles
Run Code Online (Sandbox Code Playgroud)

请注意,表的主键是聚类的(显式,为了示例),并且标题列有一个非聚集唯一性约束.

以下是select操作的结果:

t_id title
---- --------------------
3    Miss
1    Mr
2    Mrs
Run Code Online (Sandbox Code Playgroud)

查看执行计划,SQL在群集主键上使用非聚集索引.我猜这解释了为什么结果按此顺序返回,但我不知道为什么它会这样做.

有任何想法吗?更重要的是,任何阻止这种行为的方法?我希望按照插入的顺序返回行.

谢谢!

sql-server clustered-index sql-execution-plan non-clustered-index

5
推荐指数
2
解决办法
3976
查看次数

如何根据解释优化mysql查询.(类型:全部

我运行以下mysql查询并查看第一个查询的类型为ALL.

   mysql> EXPLAIN  
           SELECT one.language_id as filter_id, 
                  one.language_name as filter_name, 
                  two.count as count 
           FROM   books_f9_languages one 
           INNER JOIN (SELECT language_id, 
                       count(*) as count 
                       FROM link_f9_books_lists 
                       WHERE books_list_id IN (1691,1,2,3,4,6,7,8,9,10,11,12,13,14,17,18,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,36,37,43,44,47,51,54,57,58,59,68,71,76,77,86,88,93,94,99,120,125,126,127,133,146,147,148,257,260,261,262,263,264,266,267,268,269,270,271,272,275,276,286,767,768,769,771,772,774,777,779,783,785,786,790,792,799,808,811,813,814,815,819,825,828,829,847,850,852,853,855,856,857,858,862,863,866,869,873,875,882,891,900,907,917,925,930,935,1092,1531,1532,1533,1534,1535,1536,1537,1538,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1556,1557,1558,1560,1561,1563,1564,1565,1567,1568,1569,1570,1571,1572,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1586,1588,1589,1590,1591,1592,1595,1597,1599,1600,1601,1603,1604,1605,1606,1607,1608,1609,1610,1612,1613,1614,1615,1616,1617,1620,1621,1622,1623,1624,1625,1627,1628,1629,1630,1632,1636,1637,1638,1639,1640,1642,1643,1644,1645,1646,1648,1649,1651,1652,1653,1654,1659,1660,1662,1665,1675,1677,1679,1680,1689,1692,1693,1696,1698,1699,1702,1703,1705,1711,1713,1714,1716,1717,1719,1720,1726,1728,1729,1732,1734,1735,1736,1738,1743,1744,1753,1754,1755,1756,1759,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1797,1837,827) GROUP BY language_id) two 
          WHERE one.language_id = two.language_id 
          ORDER BY filter_name;
Run Code Online (Sandbox Code Playgroud)

这是输出,

+----+-------------+---------------------+--------+---------------+---------------+---------+-----------------+------+-----------------------------------------------------------+
| id | select_type | table               | type   | possible_keys | key           | key_len | ref             | rows | Extra                                                     |
+----+-------------+---------------------+--------+---------------+---------------+---------+-----------------+------+-----------------------------------------------------------+
|  1 | PRIMARY     | <derived2>          | ALL    | NULL          | NULL          | NULL    | NULL …
Run Code Online (Sandbox Code Playgroud)

mysql optimization sql-execution-plan

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

T-SQL - 使用非最佳计划 - WHERE子句应该短路

我们有许多"搜索存储过程",它们采用多个可空参数来搜索不同表中的数据行.它们通常是这样构建的:

SELECT      *
 FROM       Table1 T1
 INNER JOIN Table2 T2
     ON     T2.something = T1.something
 WHERE      (@parameter1 IS NULL OR T1.Column1 = @parameter1)
        AND (@parameter2 IS NULL OR T2.Column2 = @parameter2)
        AND (@parameter3 IS NULL OR T1.Column3 LIKE '%' + @parameter3 + '%')
        AND (@parameter4 IS NULL OR T2.Column4 LIKE '%' + @parameter4 + '%')       
        AND (@parameter5 IS NULL OR T1.Column5 = @parameter5)
Run Code Online (Sandbox Code Playgroud)

这可以持续多达30-40个参数,我们注意到即使只提供了parameter1,执行计划也会通过其他表的索引扫描,这会显着减慢查询速度(几秒钟).测试向我们表明,只保留WHERE语句的第一行使查询立即生效.

  1. 我已经读过,短路是不可能的,但有没有解决方法或构建可能更有效的查询的方法?

  2. 我们目前通过使用相同的SELECT/FROM/JOINS的不同版本但在WHERE子句中使用不同的参数集来解决这个问题,并且根据传递的参数,我们选择要经过的正确的select语句.这很长,很乱,很难维护.

t-sql sql-server sql-execution-plan

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