我正在 makefile 中创建一堆表。我的 make 目标类似于:
TASK:
cat script.sql | mysql -v -v -v dbName
在 script.sql
中,create table
命令之一在 CPU 使用率为 100% 时无限期挂起 mysql
进程。
如果我在同一台机器上以同一用户的身份从命令行运行相同的命令,它运行良好。
$ cat script.sql | mysql -v -v -v dbName
进一步研究,结果表明 explain
在两种环境中产生不同的结果。
从 make 内部:
+----+-------------+-------+--------+---------------+---------+---------+----------------------------------------+------+----------------------------------------------------+
| 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
以产生上面的第二个结果。
最佳答案
怀疑script.sql相等。根据您的 EXPLAIN
输出。
JOIN 顺序相同,但第三个表'p' 的引用表不同。
当在 shell 中执行时,'p'
引用 'db3.d'
但在 Make 中,' p'
引用 'db2.d'
这就是我怀疑的原因。
您可以发布您的查询吗?如果 secret ,重命名表,列。如果有子查询,可以有 2 个以上的表别名。但看起来没有子查询。
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 个随机页面,这些页面用于汇总表的统计信息(该统计信息用于连接成本)。所以统计数据可能会改变每个表的打开(它是随机读取的页面)。更多示例页面准确统计。 (抱歉我的英语不好)
关于MySQL:查询在不同环境中执行不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20059755/