我有这个执行100,000次的查询。它目前运行得非常快。我只是想知道是否有更好的方法来运行它以获得更快的响应时间。
CODES TABLE = 160KB
INDEXES: INSTANCE(UNIQUE) SHORT)DESC
CODE_VALUES=10MB
INDEXES: INSTANCE(UNIQUE), INTFC_INST, CODE_INST,SHORT_DESC
INTERFACES=160KB
INDEXES: INSTANCE (UNIQUE), SHORT_DESC
id="0" operation="SELECT STATEMENT" optimizer="ALL_ROWS" search_columns="0" cost="7">
id="1" operation="NESTED LOOPS" search_columns="0" cost="7" cardinality="1" bytes="102" cpu_cost="54,820" io_cost="7" qblock_name="SEL$1" time="1">
id="2" operation="MERGE JOIN" option="CARTESIAN" search_columns="0" cost="3" cardinality="1" bytes="33" cpu_cost="23,764" io_cost="3" time="1">
object_ID="0" id="3" operation="TABLE ACCESS" option="BY INDEX ROWID" object_name="CODES" object_type="TABLE" search_columns="0" cost="2" cardinality="1" bytes="19" cpu_cost="15,443" io_cost="2" qblock_name="SEL$1" time="1">
object_ID="1" id="4" operation="INDEX" option="RANGE SCAN" object_name="CODES_SHORT_DESC_FINDX" object_type="INDEX" search_columns="1" cost="1" cardinality="1" cpu_cost="8,171" io_cost="1" qblock_name="SEL$1" access_predicates=""A"."SYS_NC00010$"='MANAGER_GROUP'" time="1"/>
id="5" operation="BUFFER" option="SORT" search_columns="0" cost="1" cardinality="1" bytes="14" cpu_cost="8,321" io_cost="1" time="1">
object_ID="2" id="6" operation="TABLE ACCESS" option="BY INDEX ROWID" object_name="INTERFACES" object_type="TABLE" search_columns="0" cost="1" cardinality="1" bytes="14" cpu_cost="8,321" io_cost="1" qblock_name="SEL$1" time="1">
object_ID="3" id="7" operation="INDEX" option="RANGE SCAN" object_name="INTERFACES_SHORT_DESC_FINDX" object_type="INDEX" search_columns="1" cost="0" cardinality="1" cpu_cost="1,050" io_cost="0" qblock_name="SEL$1" access_predicates=""C"."SYS_NC00007>
object_ID="4" id="8" operation="TABLE ACCESS" option="BY INDEX ROWID" object_name="CODE_VALUES" object_type="TABLE" search_columns="0" cost="4" cardinality="1" bytes="69" cpu_cost="31,056" io_cost="4" qblock_name="SEL$1" filter_predicates="("A"."INSTANCE"="B"."CODE_INST" AND "B"."INTFC_INST"="C"."INSTANCE")" time="1">
object_ID="5" id="9" operation="INDEX" option="RANGE SCAN" object_name="CODE_VALUES_FUN_IDX" object_type="INDEX" search_columns="1" cost="1" cardinality="4" cpu_cost="8,771" io_cost="1" qblock_name="SEL$1" access_predicates=""B"."SYS_NC00010$"='150'" time="1"/>
SELECT A.INSTANCE, C.INSTANCE, B.LONG_DESC
FROM CODES A,
CODE_VALUES B,
INTERFACES C
WHERE A.INSTANCE = B.CODE_INST
AND B.INTFC_INST = C.INSTANCE
AND TRIM (A.SHORT_DESC) = TRIM (var1)
AND TRIM (B.SHORT_DESC) = TRIM (var2)
AND TRIM (C.SHORT_DESC) = TRIM (var3)
答案 0 :(得分:2)
在WHERE和JOIN子句中避免使用TRIM函数 - > TRIM (A.SHORT_DESC) = TRIM (var1)
仅在JOIN,WHERE和GROUP子句列上创建索引并不意味着您的查询将始终快速返回所需的结果。 它是查询优化器,它为查询选择适当的索引以提供最佳性能,但查询优化器只能通过使用适当的索引来建议最佳查询计划。当您通过编写良好的查询语法来帮助它时。
在WHERE或JOIN子句中使用任何类型的函数(系统或用户定义)可以极大地降低查询性能,因为这种做法在查询优化器工作中创建了正确索引选择的障碍。 一个常见的例子是TRIM函数,它们通常由开发人员在WHERE子句中使用。
USE AdventureWorks
GO
SELECT pr.ProductID,pr.Name,pr.ProductNumber,wo.* fROM Production.WorkOrder wo
INNER JOIN Production.Product pr
ON PR.ProductID = wo.ProductID
WHERE LTRIM(RTRIM(pr.name)) = 'HL Mountain Handlebars'
GO
SELECT pr.ProductID,pr.Name,pr.ProductNumber,wo.* fROM Production.WorkOrder wo
INNER JOIN Production.Product pr
ON PR.ProductID = wo.ProductID
WHERE pr.name = 'HL Mountain Handlebars'
虽然两个查询的输出相同,但第一次查询占用了总执行时间的近99%。这个巨大的差异只是因为这些修剪函数,所以在生产数据库中我们必须避免JOIN和WHERE子句中的这些TRIM和其他函数。
所以您可以/应该做的是对数据进行更新以一劳永逸地修剪它,并在将其添加到表中时开始对其进行修剪,因此不需要修改新数据。 或者,如果由于某种原因无法实现,请查看Maurice Reeves在评论中建议的基于函数的索引。