Sud*_*kar 1 sql oracle sqlperformance sql-tuning
你们可以查看以下对Oracle DB的查询并指出错误:
SELECT t1.name FROM t1, t2 WHERE t1.id = t2.id AND t2.empno IN (1, 2, 3, …, 200)
Run Code Online (Sandbox Code Playgroud)
查询统计:
指数:
t2.empno 被编入索引.
t1.id 被编入索引.
t2.id 被编入索引.
更新
上面的查询只是我使用的查询的示例副本.下面是一个更真实的形式
解释计划

查询:
SELECT
PRODUCT_REPRESENTATION_SK
FROM
Product_Representation pr
, Design_Object do
, Files files
,EPS_STATUS epsStatus
,EPS_ERROR_CODES epsError
,VIEW_TYPE viewTable
WHERE
pr.DESIGN_OBJECT_SK = do.DESIGN_OBJECT_SK
AND pr.LAYER_NAME !='Layer 0'
AND epsStatus.EPS_STATUS_SK = pr.EPS_STATUS
AND epsError.EPS_ERROR_CODE = pr.EPS_ERROR_CODE
AND viewTable.VIEW_TYPE_ID = pr.VIEW_TYPE_ID
AND files.pim_id = do.PIM_ID
AND do.DESIGN_OBJECT_ID IN
(
147086,149924,140458,135068,145197,134774,141837,138568,141731,138772,143769,141739,149113,148809,141072,141732,143974,147076,143972,141078,141925,134643,139701,141729,147078,139120,137097,147072,138261,149700,149701,139127,147070,149702,136766,146829,135762,140155,148459,138061,138762............................................. 200 such numbers
)
Run Code Online (Sandbox Code Playgroud)
Colled Colums:
pr.DESIGN_OBJECT_SK
do.DESIGN_OBJECT_SK
do.DESIGN_OBJECT_ID
files.pim_id
Run Code Online (Sandbox Code Playgroud)
表
TABLE "PIM"."DESIGN_OBJECT"
(
"DESIGN_OBJECT_SK" NUMBER(*,0) NOT NULL ENABLE,
"PIM_ID" NUMBER(*,0) NOT NULL ENABLE,
"DESIGN_OBJECT_TYPE_SK" NUMBER(*,0) NOT NULL ENABLE,
"DESIGN_OBJECT_ID" VARCHAR2(40 BYTE) NOT NULL ENABLE,
"DIVISION_CD" NUMBER(*,0),
"STAT_IND" NUMBER(*,0) NOT NULL ENABLE,
"STAT_CHNG_TMST" TIMESTAMP (6),
"CRTD_BY" VARCHAR2(45 BYTE),
"CRT_TMST" TIMESTAMP (6),
"MDFD_BY" VARCHAR2(45 BYTE),
"CHNG_TMST" TIMESTAMP (6),
"UPDATE_CNT" NUMBER(*,0),
"GENDER" VARCHAR2(1 BYTE),
PRIMARY KEY ("DESIGN_OBJECT_SK")
)
TABLESPACE "PIM" ENABLE,
FOREIGN KEY ("DESIGN_OBJECT_TYPE_SK")
REFERENCES "PIM"."DESIGN_OBJECT_TYPE" ("DESIGN_OBJECT_TYPE_SK")
ON DELETE CASCADE ENABLE,
FOREIGN KEY ("PIM_ID")
REFERENCES "PIM"."FILES" ("PIM_ID")
ON DELETE CASCADE ENABLE
)
Run Code Online (Sandbox Code Playgroud)
表2
CREATE TABLE "PIM"."PRODUCT_REPRESENTATION"
(
"PRODUCT_REPRESENTATION_SK" NUMBER(*,0) NOT NULL ENABLE,
"DESIGN_OBJECT_SK" NUMBER(*,0) NOT NULL ENABLE,
"VIEW_TYPE_ID" NUMBER(*,0) NOT NULL ENABLE,
"LAYER_NAME" VARCHAR2(255 BYTE),
"STAT_IND" NUMBER(*,0) NOT NULL ENABLE,
"STAT_CHNG_TMST" TIMESTAMP (6),
"CRTD_BY" VARCHAR2(45 BYTE),
"CRT_TMST" TIMESTAMP (6),
"MDFD_BY" VARCHAR2(45 BYTE),
"CHNG_TMST" TIMESTAMP (6),
"UPDATE_CNT" NUMBER(*,0),
"EPS_STATUS" VARCHAR2(30 BYTE) NOT NULL ENABLE,
"EPS_GENERATED_TIME" TIMESTAMP (6),
"EPS_ERROR_CODE" NUMBER,
"EPS_ERROR_DETAILS" VARCHAR2(500 BYTE),
"DEEPSERVER_ASSET_LAYER_ID" VARCHAR2(255 BYTE),
"PRODUCT_REPRESENTATION_LOC" VARCHAR2(255 BYTE),
PRIMARY KEY ("PRODUCT_REPRESENTATION_SK")
)
TABLESPACE "PIM" ENABLE,
FOREIGN KEY ("DESIGN_OBJECT_SK")
REFERENCES "PIM"."DESIGN_OBJECT" ("DESIGN_OBJECT_SK")
ON DELETE CASCADE ENABLE,
FOREIGN KEY ("VIEW_TYPE_ID")
REFERENCES "PIM"."VIEW_TYPE" ("VIEW_TYPE_ID")
ON DELETE CASCADE ENABLE,
CONSTRAINT "EPS_ERROR_CODE_FK"
FOREIGN KEY ("EPS_ERROR_CODE")
REFERENCES "PIM"."EPS_ERROR_CODES" ("EPS_ERROR_CODE")
ON DELETE CASCADE ENABLE,
CONSTRAINT "EPS_STATUS_FK"
FOREIGN KEY ("EPS_STATUS")
REFERENCES "PIM"."EPS_STATUS" ("EPS_STATUS_SK")
ON DELETE CASCADE ENABLE
)
Run Code Online (Sandbox Code Playgroud)
首先出错的是使用implict join语法.这是一个SQL反模式.
如果你在IN子句中有一个大的列表,你是否尝试过将它们放在一个表中并使用连接?
什么数据库?您是否查看过您的解释计划或执行计划,以了解减速的位置?
让我们忘记一下这个empno BETWEEN 1 and 200建议,并假设你有t2.empno IN (3,7,...,5209)200个参赛作品.
您还可以将查询(这是一个隐藏的JOIN查询)写入非等效的 EXISTS查询,该查询将显示相同的结果(但可能更少的行)并且应该比JOIN更快:
SELECT
t1.name
FROM
t1
WHERE EXISTS
( SELECT *
FROM t2
WHERE t2.id = t1.id
AND t2.empno IN (3,7,...,5209)
)
Run Code Online (Sandbox Code Playgroud)
(狂野猜测)
如果另一方面,它甚至t2.empno IN (3,7,...,5209)不是,t2.empno IN (SELECT tx.empno FROM tx WHERE someConditions) 而你正在使用MySQL,那么这就是你问题的根源(众所周知,MySQL无法field IN (SELECT f FROM x)以最佳方式处理).因此,您可以将查询更改为:
SELECT
t1.name
FROM
t1
JOIN t2
ON t2.id = t2.id
JOIN tx
ON tx.empno = t2.empno
WHERE
someConditions
Run Code Online (Sandbox Code Playgroud)
甚至:
SELECT
t1.name
FROM
t1
WHERE EXISTS
( SELECT *
FROM t2
JOIN tx
ON tx.empno = t2.empno
WHERE t2.id = t1.id
AND someConditions
)
Run Code Online (Sandbox Code Playgroud)