2017-09-04 27 views
0

我有一些问题与找到一个令某些过滤器的下一个ID就可以查询 - 就像它应该是从一个特定城市等PHP - SQL优化最小/最大速度太慢

目前,它被用于一个功能,它会根据当前的顺序吐出前一个或下一个ID。所以它可以是min(id)或max(id),其中max(id)明显更快,因为它必须经历更少的行。

该查询工作得很好,但它很慢,因为它要经过123953行来查找ID。有什么办法可以优化这个吗?

功能例如:

SELECT $minmax(orders.orders_id) AS new_id FROM orders LEFT JOIN orders_status ON orders.orders_status = orders_status.orders_status_id $where_join WHERE orders_status.language_id = '$languages_id' AND orders.orders_date_finished != '1900-01-01 00:00:00' AND orders.orders_id $largersmaller $ordersid $where; 

活生生的例子

SELECT min(orders.orders_id) 
FROM orders 
LEFT JOIN orders_status ON orders.orders_status = orders_status.orders_status_id 
WHERE orders_status.language_id = '4' 
    AND orders.orders_date_finished != '1900-01-01 00:00:00' 
    AND orders.orders_id < 4868771 
LIMIT 1 
+1

对orders.orders_id有一个索引并删除orders_products和products的连接。无论如何你都不使用这两张表。 where子句将你的左连接变为orders_status成为内连接,顺便说一句。 – fancyPants

+0

是date_finished的关键吗?那么这个日期怎么会是1900-01-01?除非你正在处理一些历史数据,否则NULL不会是更多的逻辑值(因为我认为这是1900年左右) –

+0

@IvoP这是一个真实的遗留系统,充满了缺陷 - 因此,为什么它不是完全逻辑的或最佳 – Dandersen

回答

0

这样的结论:

SELECT orders.orders_id 
FROM orders 
JOIN orders_status ON orders.orders_status = orders_status.orders_status_id 
WHERE orders_status.language_id = '4' 
    AND orders.orders_date_finished != '1900-01-01 00:00:00' 
    AND orders.orders_id < 4868771 
ORDER BY orders.orders_id ASC 
LIMIT 1 

附加:

,以获得最大价值,使用DESC其中ASC是现在。

并看着你的问题:一定要逃避像$ language_id etcetera这样的值。我想他们可能来自一些HTML表单? (或使用预先准备好的语句)