简单计数查询的成本
Posted
技术标签:
【中文标题】简单计数查询的成本【英文标题】:Cost Of Simple count Query 【发布时间】:2015-09-18 06:38:19 【问题描述】:我有一个关于表的简单计数的查询。根据下面的屏幕截图,除了单个索引在不同的列上之外,表上没有主键。
如何降低此查询的成本?
实际查询是:
即使我在 transactionno 列上创建了一个额外的索引,成本也没有差异。该表有 45 列。表的总大小为 520MB。
CREATE TABLE TBL_COUNT
( ROW_NUMBER NUMBER(22,0) NOT NULL ENABLE,
DATECREATED TIMESTAMP (6),
TRANSACTIONDATE VARCHAR2(64),
TRANSACTIONTIME VARCHAR2(64),
TRANSACTIONNO VARCHAR2(100),
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
REG_NO VARCHAR2(30),
EMAIL VARCHAR2(100),
PURCHASE_TYPE VARCHAR2(50),
RA_STATUS VARCHAR2(50),
BSCS_CODE VARCHAR2(20),
ORACLE_ITEM_CODE VARCHAR2(100),
ORACLE_PACKAGE_CODE VARCHAR2(100),
SKU_CODE VARCHAR2(50),
ITEM_DESCRIPTIONS VARCHAR2(100),
MSISDN VARCHAR2(150),
QUANTITY NUMBER(22,0),
UNIT_PRICE NUMBER(22,2),
SERVICE_TAX NUMBER(22,2),
TOTAL_PRICE NUMBER(22,2),
PAYMENT_METHOD VARCHAR2(50),
PAYMENT_CHANNEL VARCHAR2(50),
PAYMENT_MERCHANT_ID VARCHAR2(50),
REGISTER_REGION VARCHAR2(30),
AR_INTERFACESTATUS VARCHAR2(30),
PAYMENT_STATUS VARCHAR2(30),
PAYMENT_DATE VARCHAR2(64),
PAYMENT_TIME VARCHAR2(64),
ISSUING_BANK VARCHAR2(50),
CREDIT_CARD_NO VARCHAR2(50),
CREDIT_CARD_REASON_CODE VARCHAR2(100),
BANK_APPROVAL_CODE VARCHAR2(30),
BANK_REGISTER_REGION VARCHAR2(30),
BANK_REF_NO VARCHAR2(30),
PRIMARY_CONTACT_NO VARCHAR2(30),
ALTERNATE_CONTACT_NO VARCHAR2(30),
REFERENCE_CONTACT_NO VARCHAR2(30),
PRODUCT_UID VARCHAR2(30),
BANK_BIN VARCHAR2(50),
SETTLEMENT_DATE TIMESTAMP (3),
SKU_TYPE VARCHAR2(50),
EXTERNAL_ORDER_NUMBER VARCHAR2(64),
GST_TAX_AMOUNT NUMBER(22,2),
GST_TAX_CODE VARCHAR2(255 )
) TABLESPACE TS ;
CREATE INDEX USER.TBL_COUNT_INDEX ON USER.TBL_COUNT (DATECREATED)
TABLESPACE TS_IDX ;
【问题讨论】:
为什么你经常对大约 150 万行表执行count(*)
足以关心查询的性能?除非您想定义主键(无论如何您都应该这样做),否则不可能有比执行表扫描更有效的方法。您可能会并行化查询,这会使其返回更快,但也会导致它在服务器上消耗更多资源。
更新了问题..请就此提出建议。
您的编辑未在transactionNo
上显示索引。你确定你创建了那个索引吗?
我已经在 transactionno 上创建了索引。但由于我没有发现成本有任何改善,所以我放弃了
您很可能需要索引,而您的问题可能归结为询问为什么查询不使用索引。发布您用于创建索引的 DDL。该指数的统计数据是否准确? transactionNo
的选择性如何?您是否绑定了正确的数据类型? transactionNo
似乎被定义为 varchar2
,尽管名称暗示它是数字。
【参考方案1】:
任何索引都可以用于计数,只要它基于限制为 NOT NULL 的列,或者如果它保证为每一行保存一个值 - 例如位图索引,或 (my_column, 0) 上的索引。
或者,您可以使用 SAMPLE 子句获得估计的行数。
编辑:您说您在 transactionno 上创建了索引,并且正如 DDL 所示,它不受限制为 NOT NULL。要么在 ROW_NUMBER(唯一不为 NULL 的列)上创建索引,要么在 (transactionno, 0) 上创建基于函数的索引
【讨论】:
重点是当我正在为同一查询寻找其他表的解释计划时.. 它的成本较低,因为它使用主键。即使我在同一张表上创建了主键但没有改进,也会导致相同的成本。 请显示表和索引定义——按照您在问题中所说的方式,您创建的是索引,而不是主键。 我已经创建了主键,但是当我发现成本没有提高时,我放弃了。 请将它们添加到问题中 我在 transactionno 上创建了索引。但由于我没有发现成本有任何改善,所以我放弃了。以上是关于简单计数查询的成本的主要内容,如果未能解决你的问题,请参考以下文章