MySQL Query太复杂了

时间:2009-11-04 14:57:25

标签: sql mysql

我有一个查询,但我遇到了问题 -

这是“最好的”写作方式吗?我可以写得好多了,我听说你可以使用更多的查询'循环记录' - 这是一件好事吗?如果是这样,有人能指出我正确的方向吗?这个查询必须占用大量内存,因为它传播了8个表,包括一个包含3个表的子查询。

注意 - 我正在使用具有只读访问权限的从属数据库,因此无法更改结构/创建表等!

非常感谢您的帮助。非常感谢。

Select travel_booking.reference As REF,
  travel_group.name As `Group Name`,
  site_user.firstname As `First Name`,
  site_user.lastname As `Last Name`,
  site_user.gender,
  travel_package.start_date As `Start Date`,
  travel_booking_option.name As `Option Name`,
  travel_booking_option.text_box_text As `Free Text`,
  travel_booking_option.select_box_option As `Select Text`,
  travel_booking_option.option_price As `Option Price`,
  content.name As `Option Type`
  From travel_booking Inner Join
  travel_booking_option On travel_booking_option.travel_bookingid =
  travel_booking.travel_bookingid Inner Join
  travel_group On travel_group.travel_groupid = travel_booking.travel_groupid
Inner Join
  site_user On site_user.site_userid = travel_booking.site_userid Inner Join
  travel_option_group On travel_option_group.travel_option_groupid =
  travel_booking_option.travel_option_groupid Inner Join
  content On travel_option_group.travel_option_type_content_realid =
  content.content_realid Inner Join
  travel_package On travel_package.content_realid =
  travel_booking.travel_packageid

 Where travel_booking_option.fee = 0 And travel_booking_option.refund = 0 And
  travel_booking_option.cancel = 0 And travel_booking.cancel = 0 And
  travel_package.live = 1 And content.live = 1

Group By travel_booking.reference,
  travel_group.name,
  site_user.firstname,
  site_user.lastname,
  site_user.gender,
  travel_package.start_date,
  travel_booking_option.name,
  travel_booking_option.text_box_text,
  travel_booking_option.select_box_option,
  travel_booking_option.option_price,
  content.name

2 个答案:

答案 0 :(得分:4)

您必须查看查询的执行计划,以查看它是否效率低下。只要在执行时使用正确的索引,你应该没问题。

你问“使用更多查询''循环记录集'”。这是一种RBAR(逐行排列)方法,绝对不推荐使用。

我会重新格式化查询,使其更具可读性,如下所示:

Select 
    travel_booking.reference As REF,
    travel_group.name As `Group Name`,
    site_user.firstname As `First Name`,
    site_user.lastname As `Last Name`,
    site_user.gender,
    travel_package.start_date As `Start Date`,
    travel_booking_option.name As `Option Name`,
    travel_booking_option.text_box_text As `Free Text`,
    travel_booking_option.select_box_option As `Select Text`,
    travel_booking_option.option_price As `Option Price`,
    content.name As `Option Type`

From travel_booking 
    Inner Join travel_booking_option 
        On travel_booking_option.travel_bookingid = travel_booking.travel_bookingid 
    Inner Join travel_group 
        On travel_group.travel_groupid = travel_booking.travel_groupid
    Inner Join site_user 
        On site_user.site_userid = travel_booking.site_userid 
    Inner Join travel_option_group 
        On travel_option_group.travel_option_groupid = travel_booking_option.travel_option_groupid 
    Inner Join content 
        On travel_option_group.travel_option_type_content_realid = content.content_realid 
    Inner Join travel_package 
        On travel_package.content_realid = travel_booking.travel_packageid

Where 1=1
    And travel_booking_option.fee = 0 
    And travel_booking_option.refund = 0 
    And travel_booking_option.cancel = 0 
    And travel_booking.cancel = 0 
    And travel_package.live = 1 
    And content.live = 1

Group By 
    travel_booking.reference,
    travel_group.name,
    site_user.firstname,
    site_user.lastname,
    site_user.gender,
    travel_package.start_date,
    travel_booking_option.name,
    travel_booking_option.text_box_text,
    travel_booking_option.select_box_option,
    travel_booking_option.option_price,
    content.name

我还会为表名使用别名。

答案 1 :(得分:2)

在我看来,您对结果集中的每一列都进行了GROUPing BY,但没有聚合任何列。如果是这样,您可以通过删除最后的GROUP BY来简化,而不是在SELECT之后插入单词DISTINCT。

您还可以使用表别名缩短(但不是实际简化)查询。例如,如果您将FROM travel_booking更改为FROM travel_booking TB,则可以在整个查询过程中使用TB.代替travel_booking.。与其他表类似(当然,为每个表使用不同的别名)。

最后,如果您的应用程序不会使用列别名自动构建UI(例如,对于网格中的列标题),您也可以删除列别名。

否则查询看起来非常简单。人们有时会担心当他们的查询中有多个JOIN时出错了,但事实上,它更可能是数据库结构良好的标志。

我的SQL版本(包括列别名):

SELECT DISTINCT TB.reference As REF, TG.name As `Group Name`,
  SU.firstname As `First Name`, SU.lastname As `Last Name`, SU.gender,
  TP.start_date As `Start Date`,
  TBO.name As `Option Name`, TBO.text_box_text As `Free Text`, TBO.select_box_option As `Select Text`, TBO.option_price As `Option Price`,
  C.name As `Option Type`
 FROM travel_booking TB 
    Inner Join travel_booking_option TBO  On TBO.travel_bookingid = TB.travel_bookingid
    Inner Join travel_group TG On TG.travel_groupid = TB.travel_groupid
    Inner Join site_user SU On SU.site_userid = TB.site_userid 
    Inner Join travel_option_group TOG On TOG.travel_option_groupid = TBO.travel_option_groupid
    Inner Join content C On TOG.travel_option_type_content_realid = C.content_realid
    Inner Join travel_package TP On TP.content_realid = TB.travel_packageid
 WHERE TBO.fee = 0 And TBO.refund = 0 And TBO.cancel = 0 
    And TB.cancel = 0 And TP.live = 1 And C.live = 1