0

多くのクエリで MySQL (バージョン 5.5) の左結合パフォーマンスに問題がありました。いずれの場合も、ユニオンとサブセレクトを使用してクエリを再構築することで、この問題を回避できました (本High Performance MySQLでこの例をいくつか見ました)。問題は、これが非常に厄介なクエリにつながることです。

以下は、まったく同じ結果を生成する 2 つのクエリの例です。最初のクエリは、2 番目のクエリよりも約 2 桁遅くなります。2 番目のクエリは、最初のクエリよりもはるかに読みにくくなっています。

私が知る限り、これらの種類のクエリは、インデックス作成が悪いためにパフォーマンスが低下しているわけではありません。すべての場合において、クエリを再構築すると、問題なく実行されます。また、インデックスを注意深く見て、ヒントを使用して無駄にしようとしました。

他の誰かが MySQL で同様の問題に遭遇しましたか? 微調整を試みるべきサーバー パラメータはありますか? この種の問題を回避するためのよりクリーンな方法を見つけた人はいますか?

クエリ 1

select
  i.id,
  sum(vp.measurement * pol.quantity_ordered) measurement_on_order
from items i
left join (vendor_products vp, purchase_order_lines pol, purchase_orders po) on
  vp.item_id = i.id and
  pol.vendor_product_id = vp.id and
  pol.purchase_order_id = po.id and
  po.received_at is null and
  po.closed_at is null
group by i.id

explain:
+----+-------------+-------+--------+-------------------------------+-------------------+---------+-------------------------------------+------+-------------+
| id | select_type | table | type   | possible_keys                 | key               | key_len | ref                                 | rows | Extra       |
+----+-------------+-------+--------+-------------------------------+-------------------+---------+-------------------------------------+------+-------------+
|  1 | SIMPLE      | i     | index  | NULL                          | PRIMARY           | 4       | NULL                                |  241 | Using index |
|  1 | SIMPLE      | po    | ref    | PRIMARY,received_at,closed_at | received_at       | 9       | const                               |    2 |             |
|  1 | SIMPLE      | pol   | ref    | purchase_order_id             | purchase_order_id | 4       | nutkernel_dev.po.id                 |    7 |             |
|  1 | SIMPLE      | vp    | eq_ref | PRIMARY,item_id               | PRIMARY           | 4       | nutkernel_dev.pol.vendor_product_id |    1 |             |
+----+-------------+-------+--------+-------------------------------+-------------------+---------+-------------------------------------+------+-------------+

クエリ 2

select
  i.id,
  sum(on_order.measurement_on_order) measurement_on_order
from (
  (
    select
      i.id item_id,
      sum(vp.measurement * pol.quantity_ordered) measurement_on_order
    from purchase_orders po
    join purchase_order_lines pol on pol.purchase_order_id = po.id
    join vendor_products vp on pol.vendor_product_id = vp.id
    join items i on vp.item_id = i.id
    where
      po.received_at is null and po.closed_at is null
    group by i.id
  )
  union all
  (select id, 0 from items)
) on_order
join items i on on_order.item_id = i.id
group by i.id

explain:
+------+--------------+------------+--------+-------------------------------+--------------------------------+---------+-------------------------------------+------+----------------------------------------------+
| id   | select_type  | table      | type   | possible_keys                 | key                            | key_len | ref                                 | rows | Extra                                        |
+------+--------------+------------+--------+-------------------------------+--------------------------------+---------+-------------------------------------+------+----------------------------------------------+
|  1   | PRIMARY      | <derived2> | ALL    | NULL                          | NULL                           | NULL    | NULL                                | 3793 | Using temporary; Using filesort              |
|  1   | PRIMARY      | i          | eq_ref | PRIMARY                       | PRIMARY                        | 4       | on_order.item_id                    |    1 | Using index                                  |
|  2   | DERIVED      | po         | ALL    | PRIMARY,received_at,closed_at | NULL                           | NULL    | NULL                                |   20 | Using where; Using temporary; Using filesort |
|  2   | DERIVED      | pol        | ref    | purchase_order_id             | purchase_order_id              | 4       | nutkernel_dev.po.id                 |    7 |                                              |
|  2   | DERIVED      | vp         | eq_ref | PRIMARY,item_id               | PRIMARY                        | 4       | nutkernel_dev.pol.vendor_product_id |    1 |                                              |
|  2   | DERIVED      | i          | eq_ref | PRIMARY                       | PRIMARY                        | 4       | nutkernel_dev.vp.item_id            |    1 | Using index                                  |
|  3   | UNION        | items      | index  | NULL                          | index_new_items_on_external_id | 257     | NULL                                | 3380 | Using index                                  |
| NULL | UNION RESULT | <union2,3> | ALL    | NULL                          | NULL                           | NULL    | NULL                                | NULL |                                              |
+------+--------------+------------+--------+-------------------------------+--------------------------------+---------+-------------------------------------+------+----------------------------------------------+
4

0 に答える 0