我有一个sql语句,我加入了4个表,每个表有200K行.查询运行,但一直冻结.当我在3个表上进行连接时,它返回行(大约需要10个).有什么建议吗?建议加快?
谢谢!
码
SELECT *
FROM equipment, tiremap, workreference, tirework
WHERE equipment.tiremap = tiremap.`TireID` AND
tiremap.`WorkMap` = workreference.`aMap` AND
workreference.`bMap` = tirework.workmap
LIMIT 5
P.S
如果它有帮助,我使用sql炼金术来生成这个代码,sqlalchemy代码是这样的
query = session.query(equipment, tiremap, workreference, tirework)
query = query.filter(equipment.c.tiremap == tiremap.c.TireID)
query = query.filter(tiremap.c.WorkMap==workreference.c.aMap)
query = query.filter(workreference.c.bMap == tirework.c.workmap)
query = query.limit(5)
query.all()
解决方法:
确保您有索引:
>设备(轮胎图)
>轮胎地图(TireID)
>轮胎地图(工作地图)
>工作参考(aMap)
>工作参考(bMap)
>轮胎工作(工作地图)
编辑:我想我应该为完整性提供一些背景信息.
sql优化器查看语句,解析它,然后根据查询,引用的表和可用索引确定它的执行计划.如果你执行SELECT * FROM tab1,那么它将对tab1进行全表扫描,因为没有其他方法可以执行它.
如果您执行SELECT * FROM person WHERE lastname LIKE’V%’并且您有一百万条记录,则查询每一行的速度会很慢,但如果lastname被编入索引,则效率会更高.
使用像您这样的查询,其中一个表将成为驱动表,无论索引如何都可以简单地作为全表扫描完成.这没什么不对.一个表必须驱动查询.如果有一个WHERE子句(对于除连接条件之外的其他内容),这可能会改变,但是否则通常是正确的.
从该驱动表开始,MysqL将开始将连接附加到执行计划中.这些连接将需要另一端的索引才能有效地工作.
因此,对于三个表,您可能有一个未编入索引的表但无关紧要,因为它驱动查询.对于第四个表,可能有两个未编制索引的表,现在这是一个问题,因为对于一个MysqL中的每一行,必须对另一个进行全表扫描.
因此,基本上您可以在每个外键和连接列上创建索引,以便MysqL可以使用可用的内容为您提供的查询制定最佳执行计划.
最后,大多数工具会告诉您有关数据库架构的信息. PHPMyAdmin是托管数据库的流行版本.我个人真的喜欢这种桌面应用程序. Navicat Lite是一个不错的免费工具.