查询不使用索引 -

时间:2013-05-24 09:00:56

标签: sql database oracle indexing

我的问题涉及Oracle 11gr2以及SQL查询中索引的使用。 请帮我解决下面的问题,我无法在此查询中使用索引:

SELECT ListingManagerID,
       FirstName,
       LastName,
       PrimaryPhone,
       AlternatePhone,
       Email,
       UserName,
       Password,
       RecallGuid,
       CustomerSince,
       PWChangeRequired,
       PWExpireDate,
       CallingHours,
       CreateDate,
       CreateIPAddress,
       LastLogin,
       AutoRenewFlag,
       LastUpdated,
       UpdatedBy,
       AutoRenewRemovedDate,
       AutoRenewDate,
       isSupplier,
       PrefferedLanguage,
       AboutMe,
       PictureFilePath,
       IsProfilePictureDisplay,
       LocaleID,
       Address1,
       Address2,
       CityID,
       CountryID,
       StateProvinceID,
       PostalCode,
       RegistrationSource,
       PPCTypeID,
       GhostUser,
       ProfileId,
       TimezoneID,
       OCA
FROM ListingManager
WHERE trim(lower(LISTINGMANAGERID)) = 'e.kkagacoe4aaae7rnr9lua5'
  1. 创建索引
  2. SQL> CREATE INDEX IDX_LISTINGMANAGER_ID ON listingmanager (LOWER(listingmanagerid));

    已创建索引。

    1. 收集统计数据
    2. SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('INTERSHOP', 'LISTINGMANAGER' , CASCADE=>TRUE);

      PL / SQL程序已成功完成。

      索引是在Listingmanager Column上创建的,但仍然执行计划显示全表扫描。我不知道为什么还会发生全表扫描。

      ListingManagerID是表的主键,我可以修改主键创建的索引吗?

      PLAN_TABLE_OUTPUT
      --------------------------------------------------
      | Id | Operation        | Name           | Rows | Bytes | Cost (%CPU)|    
      --------------------------------------------------
      | 0  | SELECT STATEMENT |                | 2013 | 487K| 1784 (1)|    
      |* 1 | TABLE ACCESS FULL| LISTINGMANAGER | 2013 | 487K| 1784 (1)|
      

      谓词信息(由操作ID标识):

      1 - filter(TRIM(LOWER("LISTINGMANAGERID"))='e.kkagacoe4aaae7rnr9lua5' )
      

      由于

2 个答案:

答案 0 :(得分:5)

Oracle的功能索引非常敏感。您必须使用几乎完全用于在查询中创建索引的内容。我不是100%肯定,但甚至可能扩展到空白和括号。在任何情况下,您的索引都没有被修剪,因此它不会用在修剪的谓词上。

修剪&小写您的常量/参数而不是列(和/或存储修剪的,降低的副本),因此您根本不必使用基于函数的索引。如果列上有函数,则很难使用索引。

答案 1 :(得分:3)

您需要创建此索引,而不是您创建的索引:

CREATE INDEX IDX_LISTINGMANAGER_ID ON listingmanager (trim(LOWER(listingmanagerid)));

案例是功能索引应该与WHERE子句中的条件完全相同。

你也可以使用这个技巧来使索引工作:

SELECT 
  <fields>
FROM ListingManager
WHERE lower(LISTINGMANAGERID) like '%e.kkagacoe4aaae7rnr9lua5%'
AND trim(lower(LISTINGMANAGERID)) = 'e.kkagacoe4aaae7rnr9lua5'

但它被它的耳朵所吸引。另外你应该知道有时优化器认为FULL TABLE SCAN是一种更有效的方法来检索数据而不是使用索引,但我认为不是在你的情况下(为了使优化器使用索引,你应该使用{{3} })。

例如,您的查询使用提示:

SELECT /*+ INDEX (ListingManager IDX_LISTINGMANAGER_ID)*/
       ListingManagerID,
       FirstName,
       LastName,
       PrimaryPhone,
       AlternatePhone,
       Email,
       UserName,
       Password,
       RecallGuid,
       CustomerSince,
       PWChangeRequired,
       PWExpireDate,
       CallingHours,
       CreateDate,
       CreateIPAddress,
       LastLogin,
       AutoRenewFlag,
       LastUpdated,
       UpdatedBy,
       AutoRenewRemovedDate,
       AutoRenewDate,
       isSupplier,
       PrefferedLanguage,
       AboutMe,
       PictureFilePath,
       IsProfilePictureDisplay,
       LocaleID,
       Address1,
       Address2,
       CityID,
       CountryID,
       StateProvinceID,
       PostalCode,
       RegistrationSource,
       PPCTypeID,
       GhostUser,
       ProfileId,
       TimezoneID,
       OCA
FROM ListingManager
WHERE trim(lower(LISTINGMANAGERID)) = 'e.kkagacoe4aaae7rnr9lua5'