0

想知道是否有人可以帮助我更好地优化这个查询,因为它需要大约 4 秒来执行。

SELECT discount.*, retailer.name AS retailer_name, 
sub_category.type AS subcategory_type 
FROM discount 
  JOIN retailer ON retailer.id = discount.retailer 
  JOIN sub_category ON sub_category.id = discount.sub_category 
WHERE discount.start_date <= 1348133607 
AND retailer.closed = 0  
AND ( discount.only_for = 'PROC' OR discount.only_for = '' ) 
ORDER BY discount.updated_on DESC LIMIT 25

我有以下索引:

  • 折扣零售商
  • 折扣.sub_category
  • 折扣.start_date
  • 零售商关闭
  • discount.only_for
4

2 回答 2

0

你应该有三个索引:

CREATE INDEX discount_ndx ON discount (only_for, start_date, retailer, sub_category);
CREATE INDEX retailer_ndx ON retailer (id, closed, name);
CREATE INDEX sub_category_ndx ON sub_category(id, type);

第一个索引允许WHERE基于only_for和的立即匹配date(您可以尝试反转索引中的这两个键;这取决于数据分布。我需要输出EXPLAIN来决定)。该retailer值允许在完全JOIN无需检索discount数据的情况下完成。

从表中,retailer您只需要id(直接连接)和closed; WHERE并且也可能值得存储name在索引中。最后,该subcategory表仅提供type,因此在其上设置索引是有意义的,除非 subcategory是一个非常薄的表,其中仅包含idtype

让我知道它是如何工作的。

于 2012-09-20T10:03:11.667 回答
0

有一次我遇到了问题。我有一个像这样的查询select * from ViewName v where v.column1 = 'ABCD'

“ABCD”是一个字符。在解释计划中,我看到 Oracle 将 FAST FULL SCAN INDEX 放在我的脚本上,这是一个糟糕的索引(它的成本是 105)。

然后,我编写了一个返回相同值的函数,并替换为select * from ViewName v where v.column1 = FUNCTIONX

有趣的是,我看到 Oracle 使用了 FULL SCAN INDEX(成本为 32)并且我的执行时间显着提高。

我不擅长优化,但我认为这可能会有所帮助

于 2012-09-20T10:33:40.340 回答