如何在 mysql 或 php 中优化或加速我的子查询
How to optimize or speed up my subquery in mysql or in php
示例查询:
SELECT
table1.t1_id,table1.name,
table2.address,
(
SELECT message
FROM table3
WHERE logid = table1.t1_id
AND message NOT LIKE "[ SYSTEM%"
ORDER BY logs
DESC LIMIT 1
) as message
FROM table1
INNER JOIN table2
ON table1.t1_id = table2.t2_id
WHERE table1.dateCreated
BETWEEN CAST('2015-01-01' as Date)
AND CAST('2015-05-30' as Date)
ORDER BY table1.dateCreated DESC
预期输出:
id | name | address | message |
注意:假设 table 1 和 table 2 有数千行,table 3 有数百万行
这样会不会快点?
SELECT table1.t1_id, table1.name,table2.address, m.message
FROM
table3 as m,
table1 INNER JOIN table2 ON table1.t1_id = table2.t2_id
WHERE table1.dateCreated
BETWEEN CAST('2015-01-01' as Date) AND CAST('2015-05-30' as Date)
and m.logid = table1.t1_id
and m.message not like "[ SYSTEM%"
having min(m.log)
ORDER BY table1.dateCreated DESC
这是您的查询的修改版本
select
t1.t1_id,
t1.name,
t2.address,
t3.message
from table1 t1
join table2 t2 on t1.t1_id = t2.t2_id
join table3 t3 on t3.logid = t1.t1_id
join(
select max(logs) as logs,logid from table3
where
message NOT LIKE "[ SYSTEM%"
group by logid
)x
on x.logs = t3.logs and x.logid = t3.logid
where
t1.dateCreated BETWEEN CAST('2015-01-01' as Date) AND CAST('2015-05-30' as Date)
ORDER BY t1.dateCreated DESC;
现在您将需要 table 上的索引,我假设所有
tables 是主键并已编入索引,因此无需在其上添加额外的索引。
需要以下索引
alter table table3 add index logs_idx(logs);
alter table table3 add index message_idx(message);
alter table table3 add index logid_idx(logid);
alter table table1 add index dateCreated_idx(dateCreated);
注意:确保在应用索引之前进行 table 备份。
示例查询:
SELECT
table1.t1_id,table1.name,
table2.address,
(
SELECT message
FROM table3
WHERE logid = table1.t1_id
AND message NOT LIKE "[ SYSTEM%"
ORDER BY logs
DESC LIMIT 1
) as message
FROM table1
INNER JOIN table2
ON table1.t1_id = table2.t2_id
WHERE table1.dateCreated
BETWEEN CAST('2015-01-01' as Date)
AND CAST('2015-05-30' as Date)
ORDER BY table1.dateCreated DESC
预期输出:
id | name | address | message |
注意:假设 table 1 和 table 2 有数千行,table 3 有数百万行
这样会不会快点?
SELECT table1.t1_id, table1.name,table2.address, m.message
FROM
table3 as m,
table1 INNER JOIN table2 ON table1.t1_id = table2.t2_id
WHERE table1.dateCreated
BETWEEN CAST('2015-01-01' as Date) AND CAST('2015-05-30' as Date)
and m.logid = table1.t1_id
and m.message not like "[ SYSTEM%"
having min(m.log)
ORDER BY table1.dateCreated DESC
这是您的查询的修改版本
select
t1.t1_id,
t1.name,
t2.address,
t3.message
from table1 t1
join table2 t2 on t1.t1_id = t2.t2_id
join table3 t3 on t3.logid = t1.t1_id
join(
select max(logs) as logs,logid from table3
where
message NOT LIKE "[ SYSTEM%"
group by logid
)x
on x.logs = t3.logs and x.logid = t3.logid
where
t1.dateCreated BETWEEN CAST('2015-01-01' as Date) AND CAST('2015-05-30' as Date)
ORDER BY t1.dateCreated DESC;
现在您将需要 table 上的索引,我假设所有 tables 是主键并已编入索引,因此无需在其上添加额外的索引。 需要以下索引
alter table table3 add index logs_idx(logs);
alter table table3 add index message_idx(message);
alter table table3 add index logid_idx(logid);
alter table table1 add index dateCreated_idx(dateCreated);
注意:确保在应用索引之前进行 table 备份。