【发布时间】:2018-05-13 09:09:24
【问题描述】:
我有一个过程,取决于我构建动态条件的参数。如果任何参数为空,我们将忽略以在 where 条件下检查此列。谁能建议我对表进行索引以获得最佳性能的最佳方法是什么?
另一个问题是假设我有一个 12 列的表。我有两个查询,其中一个在 where 条件中有三列,另一个查询在 where 条件中有八列。在这种情况下,我应该创建两个不同的索引以获得更好的性能吗?
V_sql VARCHAR2(10000):='SELECT
SV_ACC_REG.ACC_REG_ID AS ACC_REG_ID ,
SV_ACC_REG.PRODUCT_ID AS PRODUCT_ID ,
GEN_PRODUCT.FULL_NAME AS PRODUCT_NAME ,
SV_ACC_REG.STATUS AS STATUS ,
SV_ACC_REG.OPENING_DATE AS OPENING_DATE ,
SV_ACC_REG.CURRENT_BALANCE AS CURRENT_BALANCE ,
SV_ACC_REG.CLOSING_DATE AS CLOSING_DATE ,
SV_ACC_REG.REG_NO AS REG_NO ,
SV_ACC_REG.IS_WITHDRAW_BY_SINGLE AS IS_WITHDRAW_BY_SINGLE,
SV_ACC_REG.IS_SINGLE AS IS_SINGLE ,
SV_ACC_REG.IS_EXTENDABLE AS IS_EXTENDABLE ,
SV_ACC_REG.REMARKS AS REMARKS ,
SV_ACC_REG.PR_NO AS PR_NO ,
SV_ACC_REG.CREATED_ON AS CREATED_ON ,
SV_ACC_REG.CREATED_BY AS CREATED_BY ,
SV_ACC_REG.UPDATED_ON AS UPDATED_ON ,
SV_ACC_REG.UPDATED_BY AS UPDATED_BY ,
SV_ACC_REG.IS_DELETED AS IS_DELETED ,
SV_ACC_REG.DELETED_ON AS DELETED_ON ,
SV_ACC_REG.DELETED_BY AS DELETED_BY ,
SV_ACC_REG.CLIENT_TYPE AS CLIENT_TYPE ,
SV_ACC_REG.IS_TRANSFER AS IS_TRANSFER ,
SV_ACC_REG.WITHDRAW_TYPE AS WITHDRAW_TYPE ,
SV_ACC_REG.DEATH_DATE AS DEATH_DATE ,
SV_ACC_REG.IS_MIGRATE AS IS_MIGRATE ,
SV_ACC_REG.MIGRATE_COMMENTS AS MIGRATE_COMMENTS ,
SV_ACC_REG.CHEQUE_HONOR_DATE AS CHEQUE_HONOR_DATE ,
SV_ACC_REG.SO_NO AS SO_NO ,
SV_ACC_REG.IS_MINOR AS IS_MINOR ,
SV_ACC_REG.NAME AS NAME ,
SV_ACC_REG.IS_OLD AS IS_OLD ,
SV_ACC_REG.IS_NO_PROFIT_CALC AS IS_NO_PROFIT_CALC ,
SV_ACC_REG.IS_SIX_M_PROFIT_CALC AS IS_SIX_M_PROFIT_CALC ,
SV_ACC_REG.IS_SEND_DPMG ,
SV_CUSTOMER_INFO.CUSTOMER_NAME AS CUSTOMER_NAME
FROM SV_ACC_REG
LEFT JOIN GEN_PRODUCT ON SV_ACC_REG.PRODUCT_ID=GEN_PRODUCT.PRODUCT_NO
LEFT JOIN SV_CUSTOMER_INFO ON SV_ACC_REG.ACC_REG_ID = SV_CUSTOMER_INFO.ACC_REG_ID';
V_WHERE VARCHAR2(500):=' WHERE ';
BEGIN
BEGIN
V_WHERE:=' WHERE ';
IF p_ACC_REG_ID IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.ACC_REG_ID = '||p_ACC_REG_ID||' AND';
END IF;
IF p_PRODUCT_ID IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.PRODUCT_ID = '||p_PRODUCT_ID||' AND';
END IF;
IF p_STATUS IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.STATUS = '||p_STATUS||' AND';
END IF;
IF p_IS_TRANSFER IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.IS_TRANSFER = '||p_IS_TRANSFER||' AND';
END IF;
IF p_SO_NO IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.SO_NO = '||p_SO_NO||' AND';
END IF;
IF p_IS_OLD IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.IS_OLD = '||p_IS_OLD||' AND';
END IF;
IF p_IS_SEND_DPMG IS NOT NULL THEN
V_WHERE := V_WHERE || ' SV_ACC_REG.IS_SEND_DPMG = '||p_IS_SEND_DPMG||' AND';
END IF;
IF p_IS_SIX_M_PROFIT_CALC IS NOT NULL THEN
V_WHERE := V_WHERE || ' IS_SIX_M_PROFIT_CALC= '||p_IS_SEND_DPMG||' AND';
END IF;
IF LENGTH(' WHERE ') =7 THEN
V_sql :=V_sql ||' ORDER BY SV_ACC_REG.ACC_REG_ID ASC';
ELSE
V_sql :=V_sql || SUBSTR(V_WHERE, 1, LENGTH(V_WHERE) - 3) ||' ORDER BY SV_ACC_REG.ACC_REG_ID ASC';
END IF;
--V_sql :=SUBSTR(V_sql, 1, LENGTH(V_sql) - 3);
--OPEN cur_OUT FOR V_sql USING p_ACC_REG_ID, p_PRODUCT_ID,p_STATUS,p_IS_TRANSFER,p_SO_NO,p_IS_OLD,p_IS_SEND_DPMG,p_IS_SIX_M_PROFIT_CALC;
OPEN cur_OUT FOR V_sql ;
END;
END;
【问题讨论】:
-
这里的标准方法是确定将出现哪些列组合,然后为每个组合构建连接索引,并避免每列有 1 个索引。或者,我的第一个尝试是识别“标题”列(希望只是少数),其中一个将出现在任何给定的组合中并为它们编制索引,然后通过向这些索引添加辅助列来微调这些索引。跨度>
-
WHERE 子句中列的基数是多少?我假设列
IS_TRANSFER或STATUS的值非常少,很可能只有 2 个。 -
这张表有多少行?
-
@APC SV_ACC_REG 表中大约有 560 万个