如何在 mysql 或 php 中优化或加速我的子查询

Posted

技术标签:

【中文标题】如何在 mysql 或 php 中优化或加速我的子查询【英文标题】:How to optimize or speed up my subquery in mysql or in php 【发布时间】:2015-05-09 08:00:21 【问题描述】:

示例查询:

 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 |

注意:假设表 1 和表 2 有数千行,而表 3 有数百万行

【问题讨论】:

您的查询需要多长时间才能执行?我的意思是基准。 根据 phpmyadmin 显示第 0 - 29 行(总共 1,002 行,查询耗时 27.2299 秒)。 您能否以创建表的形式发布 SQL Fiddle 或数据库架构,并插入带有示例数据的语句? 您是否尝试过加入表 3 并使用 GROUP BY table1&2.columns 然后 MAX(table3.message)? 演员表好像没必要 【参考方案1】:

这是您查询的修改版本

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;

现在您将需要表上的索引,我假设所有表的 id 表是主键并被索引,因此无需在它们上添加额外的索引。 需要以下索引

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);

注意:确保在应用索引之前进行表备份。

【讨论】:

嗨。创建必要的索引后,我会运行上面的查询吗? 对不起我只是一个初学者:) 是的,首先创建索引,然后再备份表。然后运行查询并查看性能。 tnx.. 从总共 1,002 个,查询耗时 27.2299 秒)到总共 1,176 个,查询耗时 1.8409 秒:D【参考方案2】:

这样更快吗?

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

【讨论】:

错误:#1111 - 组函数的使用无效 你能发布一些示例表数据吗? 你能发一些样本数据吗(咳咳,第三次问咳咳) 我请你发布示例数据,这样我就可以把它放在小提琴中,然后我可以在我发布答案之前让它工作。 只是一个小样本就可以了,每个涉及的表大约有 5 行。并确保 ID 或链接它们的任何数据匹配的表之间是否存在关系链接,就像在真实数据库中一样。

以上是关于如何在 mysql 或 php 中优化或加速我的子查询的主要内容,如果未能解决你的问题,请参考以下文章

如何优化或加速以下 sql 查询?

PHP服务缓存加速优化实战

如何在 PHP 中使用 DOM 或 XPATH 获取最近的子节点而不是嵌套的子节点

如何使用 htaccess 在 nginx 的子文件夹中运行 index.php?

如何优化 sql 查询以避免在没有 php.ini 或设置时间限制的情况下执行最长时间 [关闭]

如何在php/codeigniter或mysql中获得两个相差20分钟的日期的所有组合