编辑:更新了Bill Karwin的建议。还是很慢。
我正在尝试编写一个查询,该查询将查找订单中输入到仓库中的所有项目,该仓库中没有该仓库中该项目的记录。例如,如果为仓库A输入了项目XYZ,但仓库A实际上没有携带项目XYZ,我希望订单项目显示在我的报告中。
我能够很好地运行查询,但它似乎需要永远(50秒)。它似乎主要挂在where子句中的“is null”条件。如果我使用“is null”删除条件并运行它,它将在大约4.8秒内执行。这是我的疑问:
SELECT
saw_order.Wo,
saw_orderitem.Item,
saw_orderitem.Stock,
saw_order.`Status`,
saw_order.`Date`,
saw_orderitem.Warehouse,
saw_stockbalance.Balno,
saw_stockbalance.Stock
FROM
saw_order
Inner Join saw_orderitem ON saw_order.Wo = saw_orderitem.Wo
Inner Join saw_stock ON saw_orderitem.Stock = saw_stock.Stock
Left Join saw_stockbalance ON saw_orderitem.Stock = saw_stockbalance.Stock
AND saw_orderitem.Warehouse = saw_stockbalance.Warehouse
WHERE
saw_order.`Status` Between 3 and 81 and
saw_stockbalance.Stock Is Null
当我explain
上面的查询时,我看到了:
+----+-------------+------------------+--------+------------------------------+---------+---------+-------------------------------------------------------+-------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+--------+------------------------------+---------+---------+-------------------------------------------------------+-------+-------------------------+
| 1 | SIMPLE | saw_stock | index | PRIMARY | PRIMARY | 17 | NULL | 32793 | Using index |
| 1 | SIMPLE | saw_orderitem | ref | PRIMARY,Stock,StockWarehouse | Stock | 17 | saws.saw_stock.Stock | 68 | |
| 1 | SIMPLE | saw_order | eq_ref | PRIMARY,Status | PRIMARY | 4 | saws.saw_orderitem.Wo | 1 | Using where |
| 1 | SIMPLE | saw_stockbalance | ref | Stock,Warehouse | Stock | 20 | saws.saw_orderitem.Stock,saws.saw_orderitem.Warehouse | 1 | Using where; Not exists |
+----+-------------+------------------+--------+------------------------------+---------+---------+-------------------------------------------------------+-------+-------------------------+
我很确定我的联接中各个表的所有字段都有索引,但无法弄清楚如何重写查询以使其更快。
编辑:以下是我在桌面上设置的索引:
mysql> show index from saw_order;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_order | 0 | PRIMARY | 1 | Wo | A | 553425 | NULL | NULL | | BTREE | |
| saw_order | 1 | Customer | 1 | Customer | A | 14957 | NULL | NULL | | BTREE | |
| saw_order | 1 | Other | 1 | Other | A | 218 | NULL | NULL | | BTREE | |
| saw_order | 1 | Site | 1 | Site | A | 8 | NULL | NULL | | BTREE | |
| saw_order | 1 | Date | 1 | Date | A | 1594 | NULL | NULL | | BTREE | |
| saw_order | 1 | Status | 1 | Status | A | 15 | NULL | NULL | | BTREE | |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
6 rows in set
mysql> show index from saw_orderitem;
+---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_orderitem | 0 | PRIMARY | 1 | Wo | A | NULL | NULL | NULL | | BTREE | |
| saw_orderitem | 0 | PRIMARY | 2 | Item | A | 1842359 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | Stock | 1 | Stock | A | 27093 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | Product | 1 | Product | A | 803 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | GGroup | 1 | GGroup | A | 114 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | ShipVia | 1 | ShipVia | A | 218 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | Warehouse | 1 | Warehouse | A | 9 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | StockWarehouse | 1 | Stock | A | 27093 | NULL | NULL | | BTREE | |
| saw_orderitem | 1 | StockWarehouse | 2 | Warehouse | A | 49793 | NULL | NULL | | BTREE | |
+---------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
9 rows in set
mysql> show index from saw_stock;
+-----------+------------+-------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+-------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_stock | 0 | PRIMARY | 1 | Stock | A | 32793 | NULL | NULL | | BTREE | |
| saw_stock | 1 | Class | 1 | Class | A | 655 | NULL | NULL | YES | BTREE | |
| saw_stock | 1 | DateFirstReceived | 1 | DateFirstReceived | A | 2732 | NULL | NULL | | BTREE | |
+-----------+------------+-------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set
mysql> show index from saw_stockbalance;
+------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| saw_stockbalance | 0 | PRIMARY | 1 | Balno | A | 146315 | NULL | NULL | | BTREE | |
| saw_stockbalance | 1 | Stock | 1 | Stock | A | 36578 | NULL | NULL | | BTREE | |
| saw_stockbalance | 1 | Stock | 2 | Warehouse | A | 146315 | NULL | NULL | | BTREE | |
| saw_stockbalance | 1 | Warehouse | 1 | Warehouse | A | 11 | NULL | NULL | | BTREE | |
+------------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set
有什么想法吗?
答案 0 :(得分:1)
我会尝试使用covering index。也就是说,不测试Balno
是否为null,而是测试左外连接条件中的一列是否为空。例如。 Stock
或Warehouse
。
您还应在两个表Stock
和Warehouse
中的两列(saw_orderitem
,saw_stockbalance
)上定义索引。
答案 1 :(得分:1)
尝试:
SELECT t.wo,
soi.item,
soi.stock,
t.Status,
t.Date,
soi.warehouse,
NULL 'balno', --ssb.Balno,
NULL 'stock', --ssb.Stock
FROM SAW_ORDER t
JOIN SAW_ORDERITEM soi ON soi.wo = t.wo
JOIN SAW_STOCK ss ON ss.stock = soi.stock
WHERE t.status BETWEEN 3 AND 81
AND NOT EXISTS (SELECT NULL
FROM SAW_STOCKBALANCE ssb
WHERE ssb.stock != soi.stock
AND ssb.warehouse = soi.warehouse)
查询的问题是您正在检查LEFT JOIN上的空值...