在Oracle中对左外连接表应用索引

azpvetkf  于 2023-04-20  发布在  Oracle
关注(0)|答案(1)|浏览(224)

我有以下类型的查询,使用左外连接,但我的索引不工作,当我做解释查询:

SELECT p.ProductName,p.ProductDesc, p.ProductSize, p.ProductPrice, c.CategoryName
FROM Product p
Left Outer Join Category c ON p.Category_id = c.CategoryID
WHERE (:product_id is null or p.ProductId in (
  SELECT TRIM(regex_substr(:product_id,'[^,]+',1,level) as id)
  FROM DUAL
  WHERE TRIM(regex_substr(:product_id,'[^,]+',1,level)) is not null
  CONNECT TRIM(regex_substr(:product_id,'[^,]+',1,level) as id) is not null
))

我把索引CategoryId在表类别和产品和productId在产品,但解释查询不显示任何索引,而不是所有表都是全扫描.请建议.
它正在执行我在类别ID上添加索引的问题,因为这会导致全表扫描。
编辑:数据统计:产品表有50万条记录,类别有大约20k条记录。不知道为什么,但这个查询需要大约13分钟才能将全部数据提取到csv。我使用SQL开发人员提取数据。

lzfw57am

lzfw57am1#

一个名为“Category“的表听起来似乎只有很少的行,当连接到“Product“表时,可能几乎需要它的所有行。
在这种情况下,Oracle自然会选择全表扫描和散列连接,而不是使用索引,这个决定是正确的。不要因为索引存在就认为应该使用索引。收集两个表的统计信息,如果它仍然想避免索引,那就别管它,除非你遇到了性能问题。
我不推荐这样做,但是如果你不得不强迫它使用索引,那么你可以使用/*+ rule */提示将它转到RBO(基于规则的优化器),或者你可以使用/*+ INDEX(c) */提示指定索引。但是,我重申,你很可能不希望它在这样的表上使用索引来进行这样的查询。

相关问题