mysql的查询结构,是UNION ALL真正做到这一点的正确方法吗?

时间:2013-05-20 20:30:42

标签: mysql

我遇到一个问题,即mysql查询卡在“发送数据”状态,有时超过12-20分钟,然后我看到其他查询堆积在它后面,直到我用尽了连接和网站倒塌了。似乎他们最终完成了,如果我坐下来看他们足够长的时间他们去“删除临时表”然后他们清理出来。

现在我没有编写这段代码,但我的任务是修复它。我为我们公司做了IT和服务器管理员工作,但我把所有实际编码都留给了我的开发人员。我对mysql几乎一无所知,但我的网络人员正在使用的SELECT查询看起来很可疑。如果我正确地阅读它,他说“在每个表中查找product_id xxxx并给我这些结果,丢弃其余的”他声称因为表被索引,所以以这种方式调用数据不是问题。

如果我从mysql控制台运行查询,返回结果需要3到20秒,而当PHP实际调用它时显然更长。请注意,它不限于任何一个产品ID。我试图打电话的产品似乎没什么区别。

这就是我在mysql.log中看到的内容

    47384 Connect   ecom_a@localhost on 
    47384 Init DB   ecom_Products
    47384 Query SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'ecom_Products'
    47384 Query 
SELECT * FROM ((SELECT * FROM `AC_Electric_Motor_Run_Capacitors`) 
UNION ALL (SELECT * FROM `AC_Electric_Motor_Start_Capacitors`) 
UNION ALL (SELECT * FROM `AC_Filters`) 
UNION ALL (SELECT * FROM `AC_Gear_Motors`) 
UNION ALL (SELECT * FROM `AC_Line_&_Load_Reactors`) 
UNION ALL (SELECT * FROM `AC_Voltage_Regulators`) 
UNION ALL (SELECT * FROM `Auxiliary_Contact_Blocks`) UNION ALL (SELECT * FROM `Bleed_Down_Resistors`) UNION ALL (SELECT * FROM `Coils`) UNION ALL (SELECT * FROM `Contactors`) UNION ALL (SELECT * FROM `Crimpers`) UNION ALL (SELECT * FROM `DC_Gear_Motors`) UNION ALL (SELECT * FROM `Diesel_Engines`) UNION ALL (SELECT * FROM `Disconnects`) UNION ALL (SELECT * FROM `Electric_Motor_Slide_Bases`) UNION ALL (SELECT * FROM `Electric_Motors`) UNION ALL (SELECT * FROM `Electric_Powered_Water_Pumps`) UNION ALL (SELECT * FROM `Electrical_Enclosures`) UNION ALL (SELECT * FROM `Engine_Powered_Water_Pumps`) UNION ALL (SELECT * FROM `External_Control_Interfaces`) UNION ALL (SELECT * FROM `Float_Switches`) UNION ALL (SELECT * FROM `Foot_Switches`) UNION ALL (SELECT * FROM `Generator_Heads`) UNION ALL (SELECT * FROM `Horizontal_Shaft_Gas_Engines`) UNION ALL (SELECT * FROM `Insulating_Resins`) UNION ALL (SELECT * FROM `Limit_Switches`) UNION ALL (SELECT * FROM `Magnet_Wire`) UNION ALL (SELECT * FROM `Manual_Transfer_Switches`) UNION ALL (SELECT * FROM `Mechanical_Interlock_Blocks`) UNION ALL (SELECT * FROM `Medium_Voltage_Transformers`) UNION ALL (SELECT * FROM `Motor_Starters`) UNION ALL (SELECT * FROM `Multi-fuel_Engines`) UNION ALL (SELECT * FROM `Overload_Relays`) UNION ALL (SELECT * FROM `PTO_Generator_3-Point_Hitch_Mounts`) UNION ALL (SELECT * FROM `PTO_Generator_Drive_Adapters`) UNION ALL (SELECT * FROM `PTO_Generator_Drive_Shafts`) UNION ALL (SELECT * FROM `PTO_Generator_Trailers`) UNION ALL (SELECT * FROM `PTO_Generators`) UNION ALL (SELECT * FROM `Packaged_Standby_Generators`) UNION ALL (SELECT * FROM `Portable_Generator_Covers`) UNION ALL (SELECT * FROM `Portable_Generator_Lifting_Provisions`) UNION ALL (SELECT * FROM `Portable_Generator_Wheel_Kits`) UNION ALL (SELECT * FROM `Portable_Generators`) UNION ALL (SELECT * FROM `Resilient_Vibration_Isolators`) UNION ALL (SELECT * FROM `Resistance_Wire`) UNION ALL (SELECT * FROM `Rotary_Frequency_Converters`) UNION ALL (SELECT * FROM `Rotary_Phase_Converters`) UNION ALL (SELECT * FROM `SO_Cable`) UNION ALL (SELECT * FROM `Single_Phase_Motors_with_Base_Mount`) UNION ALL (SELECT * FROM `Single_Phase_Motors_with_Face_&_Base_Mount`) UNION ALL (SELECT * FROM `Single_Phase_Motors_with_Face_Mount`) UNION ALL (SELECT * FROM `Soft_Starters`) UNION ALL (SELECT * FROM `Special_Metal_Wire`) UNION ALL (SELECT * FROM `Static_Frequency_Converters`) UNION ALL (SELECT * FROM `Static_Phase_Converters`) UNION ALL (SELECT * FROM `Surge_Suppressors`) UNION ALL (SELECT * FROM `Three_Phase_Motors_with_Base_Mount`) UNION ALL (SELECT * FROM `Three_Phase_Motors_with_Face_&_Base_Mount`) UNION ALL (SELECT * FROM `Three_Phase_Motors_with_Face_Mount`) UNION ALL (SELECT * FROM `Transformers_-_General`) UNION ALL (SELECT * FROM `Variable_Frequency_Drives`) UNION ALL (SELECT * FROM `Variable_Transformers`) UNION ALL (SELECT * FROM `Vehicle_&_Equipment_Batteries`) UNION ALL (SELECT * FROM `Vertical_Shaft_Gas_Engines`) UNION ALL (SELECT * FROM `Welding_Cable`) UNION ALL (SELECT * FROM `_Default`)) 
AS t WHERE product_ID = 'LF0009' LIMIT 1    

3 个答案:

答案 0 :(得分:3)

假设确实有必要搜索每个表,那么每个子查询应用WHERE子句会更好。就目前而言,此查询将在应用where之前构建一个超级结果集,然后限制结果集。也许MySQL可以优化它,也许它不能,但你可以尝试:

....
UNION ALL (SELECT * FROM `AC_Filters` WHERE product_ID = 'LF0009')
UNION ALL (SELECT * FROM `AC_Line_&_Load_Reactors` WHERE product_ID = 'LF0009')
....

我怀疑这个查询是在PHP中以编程方式生成的,给出了第一个运行的查询,因此进行更改并不困难。

更广泛地说,从查询的外观来看,您似乎每个产品类型都有一个表格,而不是一个名为“products”的表,其中包含该类型的ID列,以及列出唯一产品的表。

答案 1 :(得分:2)

如果所有这些表的表结构相同,那么它们应该是一个带有额外字段的表,以区分AC_Gear_MotorsAC_Filters等。它看起来像所有表都有的原因相同的字段是因为所有字段都是从每个表中选择的并且是UNIONed。

此外,请考虑确定您实际需要的字段,而不是使用*

答案 2 :(得分:1)

这可能会表现得更好......

SELECT only, the, columns, i, actually, need
  FROM one_big_fat_properly_indexed_table t 
 WHERE product_ID = 'LF0009';

...哦,没有ORDER BY的LIMIT没什么意义,所以我把它关了。