标签: explain

为什么MySQL在这个查询中显示index_merge?

我看起来像一个相当简单的表结构,但MySQL index_merge在一个简单的查询中默认为不是最优的.

这是表结构:

CREATE TABLE IF NOT EXISTS `event_log` (
  `event_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(5) DEFAULT NULL,
  `location_id` int(10) DEFAULT NULL,
  `object_id` int(5) DEFAULT NULL,
  `action_id` int(5) DEFAULT NULL,
  `date_event` datetime DEFAULT NULL,
  PRIMARY KEY (`event_id`),
  KEY `user_id` (`user_id`),
  KEY `date_event` (`date_event`),
  KEY `action_id` (`action_id`),
  KEY `object_id` (`object_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

解析一个基本的SELECT查询

EXPLAIN SELECT date_event
FROM event_log
WHERE user_id =123
AND object_id =456
AND location_id =789 
Run Code Online (Sandbox Code Playgroud)

返回此:

select_type  table     type         possible_keys       key                 key_len     ref     rows    Extra …
Run Code Online (Sandbox Code Playgroud)

mysql indexing query-optimization explain

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

PostgreSQL解释计划中的成本测量有多可靠?

查询在具有1,100万行的大型表上执行.我已经ANALYZE在查询执行之前在表上执行了一个.

查询1:

SELECT *
FROM accounts t1
LEFT OUTER JOIN accounts t2 
    ON (t1.account_no = t2.account_no
        AND t1.effective_date < t2.effective_date)
WHERE t2.account_no IS NULL;
Run Code Online (Sandbox Code Playgroud)

解释分析:

Hash Anti Join  (cost=480795.57..1201111.40 rows=7369854 width=292) (actual time=29619.499..115662.111 rows=1977871 loops=1)
  Hash Cond: ((t1.account_no)::text = (t2.account_no)::text)
  Join Filter: ((t1.effective_date)::text < (t2.effective_date)::text)
  ->  Seq Scan on accounts t1  (cost=0.00..342610.81 rows=11054781 width=146) (actual time=0.025..25693.921 rows=11034070 loops=1)
  ->  Hash  (cost=342610.81..342610.81 rows=11054781 width=146) (actual time=29612.925..29612.925 rows=11034070 loops=1)
        Buckets: 2097152  Batches: 1  Memory Usage: 1834187kB
        ->  Seq Scan on …
Run Code Online (Sandbox Code Playgroud)

sql postgresql explain database-performance sql-execution-plan

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

使用IN子查询改进MySQL查询

我有桌子items和桌子item_attributes.

为简单起见,假设我的表项有一列id和一列name.对于cource,id列上有一个索引.

item_attributes表具有的列id,item_id,attribute_nameattribute_value和索引ONattrubute_name

现在我想查询具有特定属性的所有项目而不使用连接.

我使用以下查询执行此操作:

SELECT *
FROM items i
WHERE i.id IN (
    SELECT item_id
    FROM item_attributes a
    WHERE a.attribute_name = 'SomeAttribute'
      AND a.attribute_value = 'SomeValue'
)
Run Code Online (Sandbox Code Playgroud)

SubQuery本身运行得很快.

如果我首先执行查询本身并将结果用于IN查询

SELECT *
FROM items i
WHERE i.id IN (1,3,5,7,10,...)
Run Code Online (Sandbox Code Playgroud)

它也很快.

但是,组合查询非常非常慢(> 2秒).如果我调查查询计划,我明白为什么:MySQL对items表执行全表扫描,而不是先执行子查询并使用结果进行索引查询.

1, 'PRIMARY', 'items', 'ALL', '', '', '', '', 149726, 'Using where'
2, 'DEPENDENT SUBQUERY', 'item_attributes', 'index_subquery', 'IDX_ATTRIBUTE_NAME', …
Run Code Online (Sandbox Code Playgroud)

mysql query-optimization explain

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

mysql - OR运算符不使用索引

我有一个简单的邀请表:

CREATE TABLE `invitation` (
  `invitation_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `inviter_id` int(10) unsigned NOT NULL,
  `invitee_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`invitation_id`),
  UNIQUE KEY `invitee_inviter_idx` (`invitee_id`,`inviter_id`)
)
Run Code Online (Sandbox Code Playgroud)

我想通过邀请者70选择被邀请者62的邀请,反之亦然:

EXPLAIN SELECT * FROM `invitation` WHERE 
(invitee_id = 70 AND inviter_id = 62) OR (invitee_id = 62 AND inviter_id = 70)
Run Code Online (Sandbox Code Playgroud)

但是此查询的类型为ALL,并且不使用invitee_inviter_idx.请告诉我这里有什么问题?

谢谢!

==编辑==对不起,我错了架构,还有一个字段:request_ts.这次查询计划是ALL.

    CREATE TABLE `invitation` (
      `invitation_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `inviter_id` int(10) unsigned NOT NULL,
      `invitee_id` int(10) unsigned NOT NULL,
      `request_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, …
Run Code Online (Sandbox Code Playgroud)

mysql sql explain

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

MySQL:对ANALYZE TABLE的随机效果

我有3个innodb表,比如说A,B和C.有一个查询可以连接这三个表来生成结果.

SELECT A.a, B.b, C.c
from A 
join B on A.id = B.a_id 
join C on C.id = B.c_id
where A.a = 'example' and B.b < 10;
Run Code Online (Sandbox Code Playgroud)

在我使用'EXPLAIN'命令测试查询时,它给出了以下顺序:

B - C - A.

但是,这不是最佳的.所以我对所有表运行'ANALYZE TABLE',它给了我:

A - B - C.

,我相信这是正确的顺序.

然后我将SQL部署到生产中,并且无缘无故地,在1个月之后,执行计划切换回坏选项,即B-C-A.在那之后,我尝试了多次ANALYZE TABLE再次运行,但这一次,结果让我感到困惑.有时它也会给我B - C - A,有时它会给我A - B - C,有时甚至是其他执行计划.

所以我的问题是:

  1. 为什么部署后执行计划会发生变化?
  2. 除了固定执行计划(数据得到更新和快速变化,因此最佳计划可能在未来发生变化),有没有办法保证始终确保最佳计划?

mysql indexing explain sql-execution-plan

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

Postgresql输出EXPLAIN ANALYZE到文件

我需要知道特定查询将运行多长时间(我预计运行时间非常长).为此,我决定EXPLAIN ANALYZE在查询集上运行一个只包含整个数据集的一部分并从那里进行推断.但我有一个问题; 在连接超时之前,查询需要两个多小时,没有结果.我不想增加超时,因为我不知道可以运行多长时间(两小时到两天之间).

有没有办法可以指示SQL服务器将数据输出到服务器文件系统上的文件中,所以我不必担心超时?我尝试过以下方法:

Copy (
    EXPLAIN ANALYZE INSERT INTO <table>
    <Long complex query here>
) To '/tmp/analyze.csv' With CSV;
Run Code Online (Sandbox Code Playgroud)

但我得到一个错误EXPLAIN.

为了记录,是的,我想这样做ANALYZE是因为

  • 它减少了以后处理的数据量,并且
  • 它给出了实际的时间估计.

postgresql file explain output

4
推荐指数
2
解决办法
2973
查看次数

MySQL EXPLAIN 中的“过滤”列告诉我什么,我该如何使用它?

MySQL的5.7文档状态:

filtered列指示将由表条件过滤的表行的估计百分比。也就是说,rows显示估计的检查行数并rows × filtered / 100显示将与先前表连接的行数。

为了更好地理解这一点,我在使用MySQL Sakila 示例数据库的查询中进行了尝试。有问题的表具有以下结构:

mysql> SHOW CREATE TABLE film \G
*************************** 1. row ***************************
       Table: film
Create Table: CREATE TABLE `film` (
  `film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `description` text,
  `release_year` year(4) DEFAULT NULL,
  `language_id` tinyint(3) unsigned NOT NULL,
  `original_language_id` tinyint(3) unsigned DEFAULT NULL,
  `rental_duration` tinyint(3) unsigned NOT NULL DEFAULT '3',
  `rental_rate` decimal(4,2) NOT NULL DEFAULT '4.99',
  `length` smallint(5) unsigned DEFAULT …
Run Code Online (Sandbox Code Playgroud)

mysql sql explain sql-execution-plan

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

pymongo聚合不允许解释选项

我成功运行:

result = my_col.aggregate(my_pipeline, allowDiskUse=True)
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试:

result = my_col.aggregate(my_pipeline, allowDiskUse=True, explain=True)
Run Code Online (Sandbox Code Playgroud)

它没有说:

pymongo.errors.ConfigurationError: The explain option is not supported. Use Database.command instead.
Run Code Online (Sandbox Code Playgroud)

因此,我尝试添加所需的选项:

result = mydb.command('aggregate', 'mycol', my_pipeline, {'explain':True})
Run Code Online (Sandbox Code Playgroud)

但失败说:

pymongo.errors.OperationFailure: 'pipeline' option must be specified as an array
Run Code Online (Sandbox Code Playgroud)

怎么了?

感谢您的任何建议。

基督教

mongodb explain pymongo aggregation-framework

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

搜索表与扫描表

sqlite> .schema actor
CREATE TABLE actor (
  id INTEGER PRIMARY KEY, name TEXT, gender TEXT
  );
sqlite> explain query plan
   ...> select * from actor where id = '305453';
0|0|0|SEARCH TABLE actor USING INTEGER PRIMARY KEY (rowid=?)
sqlite> explain query plan
   ...> select * from actor where name = 'Connery, Sean';
0|0|0|SCAN TABLE actor
sqlite>
Run Code Online (Sandbox Code Playgroud)

SEARCH TABLE actor USING INTEGER PRIMARY KEY (rowid=?)与相比,花费的时间明显更少SCAN TABLE actor


很明显,由于重复的可能性,这SCAN TABLE actor是对表的彻底扫描,但是,actor

1)SCAN TABLE&SEARCH TABLE扫描B-TREE还是记录序列? …

sql sqlite explain

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

为什么带有通配符的 LIKE 查询不使用索引?

尽管标题列是通过使用以下查询添加为索引的:

ALTER TABLE Recipe ADD INDEX Title_idx (Title)
Run Code Online (Sandbox Code Playgroud)

MySQL 不使用该索引来执行此查询:

SELECT * FROM Recipe
WHERE Title LIKE '%cake%';
Run Code Online (Sandbox Code Playgroud)

我使用了EXPLAIN关键字,关键字段是NULL

怎么解决呢?我必须改进该查询。

mysql explain

3
推荐指数
2
解决办法
4377
查看次数