我在makefile中创建了一堆表。我的make目标看起来像:
TASK:
cat script.sql | mysql -v -v -v dbName
在script.sql
内,其中一个create table
命令会以{100} CPU的mysql
进程无限期挂起。
如果我在同一台机器上运行与同一用户相同的命令,但是从命令行运行,它运行正常。
$ cat script.sql | mysql -v -v -v dbName
进一步深入研究,结果发现explain
在两种环境中产生不同的结果。
从内部制作:
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 2340 | NULL |
| 1 | SIMPLE | d | index | NULL | PRIMARY | 3 | NULL | 2739 | Using index; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | p | eq_ref | PRIMARY | PRIMARY | 7 | db1.o.field1,db3.d.date | 1 | Using where |
| 1 | SIMPLE | n | ALL | PRIMARY | NULL | NULL | NULL | 1 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
从命令行:
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 2340 | NULL |
| 1 | SIMPLE | d | index | NULL | PRIMARY | 3 | NULL | 2739 | Using index; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | p | eq_ref | PRIMARY | PRIMARY | 7 | db1.o.field1,db3.d.date | 1 | Using where |
| 1 | SIMPLE | n | ref | PRIMARY | PRIMARY | 4 | db2.p.field1 | 1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
一些挖掘工作指示我this question,并且在其中一个表上运行analyze
确实解决了这个问题。
但严重的是,这里发生了什么?是否存在导致mysql
表现不同的环境变量?
有问题的查询如下所示:
drop view if exists v;
create view v as (
select *
from db1.order o
cross join db3.dates d
left join db2.price p on (1=1
and p.id = o.id
and p.date = d.date
and p.volume > 0)
left join db3.security n on (1=1
and n.id = p.id
and n.date <= d.date)
);
explain select * from v;
analyze table n;
explain select * from v;
create table t (
primary key (date asc, id asc)
) as (
select * from v
);
从make
内部,第一个explain
产生上面的第一个结果,然后analyze
导致第二个explain
产生上面的第二个结果。
答案 0 :(得分:1)
怀疑script.sql是否相同。根据您的EXPLAIN
输出。
JOIN顺序彼此相同,但第三表'p'的引用表不同。
执行在shell 时,'p'
引用'db3.d'
,但在制作,'p'
引用'db2.d'
这就是我怀疑的原因。
你可以发布你的查询吗?如果保密,重命名表,列。如果有子查询,则可以有两个以上的表别名。但看起来没有子查询。 你给我的 this question与你无关。他有新环境,表统计信息需要ANALYZE
。
弄清楚两个sql真的是同一个开启General log。这很简单。在script.sql的第一行添加SET GLOBAL general_log = 'ON'
,在sql的末尾添加SET GLOBAL general_log = 'OFF'
。
好的,script.sql清除了怀疑。然后我不知道为什么两个运行不同。 MySQL forums可能会对您有所帮助。
顺便说一句,我可以告诉你一些信息。 script.sql如何工作? CREATE VIEW
和SELECT .. FROM view
是script.sql的一部分或全部。是否在db3.security或其他表上创建或插入?如果您发布MySQL论坛,那么将更好地描述script.sql如何工作。
USE INDEX 您是否尝试过使用USE INDEX
?大多数内部表'n'
正在进行全面扫描。
innodb_stats_sample_pages 如果您使用InnoDB,最后在my.cnf中设置innodb_stats_sample_pages=64
(默认为8)。当innodb表打开时,MySQL会读取8个随机页面,这些页面用于聚合表格上的统计信息(这个统计数据用于加入成本)。因此统计数据可能会改变每个表格的开头(它是随机阅读页面)。更多样本页面准确统计。
(对不起我的英语不好)