我使用PC上的bitnami WAMP创建一个mysql服务器,并使用流动的SQL创建两个表table_a和table_b:
char message [] = "apples are better than bananas...But good as grapes?";
char *delimiter_location = strstr(message, "...");
int m1_strlen = delimiter_location - message;
// Not every C standard and every compiler supports dynamically sized arrays.
// In those cases you need to use malloc() and free().
// Or even better: strdup() or strndup().
char message_1[m1_strlen + 1];
// NB no need to call memset() because the space is written to immediately:
strncpy(message_1, message, m1_strlen);
message_1[m1_strlen] = '\0'; // This ensures a terminated string.
printf("message: %s\n", message);
printf("message 1: %s\n", message_1);
CREATE TABLE `table_a` (
`id` int(11) DEFAULT NULL,
`c_id` varchar(45) DEFAULT NULL,
`date` date DEFAULT NULL,
`value` decimal(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
当我跑步时:
CREATE TABLE `table_b` (
`id` int(11) DEFAULT NULL,
`c_id` varchar(45) DEFAULT NULL,
`status` int(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
当我跑步时:
select
t1.id,
t1.date,
t1.value
from
(
select
id,
c_id,
date,
value
from
table_a
where
id >= '7000'
and id < '10000'
)
t1
inner join
(
select
id,
c_id
from
table_b
where
status = 1
id >= '7000'
and id < '10000'
group by
id,
c_id
order by null
)
t2
on
t1.id = t2.id
and t1.c_id = t2.c_id
但是当我运行t1内部联接t2内部联接t3时,它花费了8.375秒,这是sql:
select
t1.id,
t1.date,
t1.value
from
(
select
id,
c_id,
date,
value
from
table_a
where
id >= '7000'
and id < '10000'
)
t1
inner join
(
select
id
from
(
SELECT
id,
count(*) as times
FROM
table_b
where
status = 1
and id >= '7000'
and id < '10000'
group by
id
order by null
)
t
where
times >= 2
)
t3
on t1.id = t3.id
问题的原因是什么?
答案 0 :(得分:0)
您的问题是您的表缺少索引。要使连接正常运行,需要连接键上的索引。对于第一个查询,由MySQL保存,MySQL会在存储子查询结果的临时表上自动创建索引(auto_key0)。查询2的查询计划使我感到惊讶。我原本期望与查询1类似的计划,但我不明白所示计划的执行情况和报告方式如何。另外,我不明白为什么您在第三个查询中没有获得auto_key。
无论如何,对于InnoDB表,建议始终定义主键。就您而言,我猜id
是您表中的主键。您的查询还将受益于c_id
上的二级索引。