即使使用 parallel(8) 提示,具有数百万条记录的表中的 Count(1) 也很慢
Posted
技术标签:
【中文标题】即使使用 parallel(8) 提示,具有数百万条记录的表中的 Count(1) 也很慢【英文标题】:Count(1) from a table having million records is slow even with parallel(8) hint 【发布时间】:2020-02-11 17:40:00 【问题描述】:我正在尝试从具有 1.94 亿条记录的表中计算记录。使用了并行提示和索引快速扫描,但仍然很慢。请为附加的查询提出任何替代或改进想法。
SELECT
/*+ parallel(cs_salestransaction 8)
index_ffs(cs_salestransaction CS_SALESTRANSACTION_COMPDATE)
index_ffs(cs_salestransaction CS_SALESTRANSACTION_AK1) */
COUNT(1)
FROM cs_salestransaction
WHERE processingunitseq=38280596832649217
AND (compensationdate BETWEEN DATE '28-06-17' AND DATE '26-01-18'
OR eventtypeseq IN (16607023626823731, 16607023626823732, 16607023626823733, 16607023626823734));
这是执行计划:
[]
查询给出了结果,但计算了 1.94 亿需要 2 个小时。
编辑:
编辑代码以根据 Littlefoot 的建议添加 DATE。 使用实际列名编辑的代码。 我是堆栈溢出的新手,因此已将计划附加为图像。
【问题讨论】:
什么是es执行计划? @WernfriedDomscheit 已将其作为图像附加。我是堆栈溢出的新手。所以不知道如何以可读的格式复制粘贴它。 通常您会使用EXPLAIN PLAN FOR ... your statement;
和SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
或SELECT DBMS_XPLAN.DISPLAY_PLAN from dual;
获得解释计划
"parallel(8) 提示":那么您的数据库服务器有多少 CPU?您执行此查询时还运行了什么?
@APC 这是我查询缓慢的原因之一。许多会话在后台运行。谢谢
【参考方案1】:
另外,如果compensationdate
是DATE
数据类型,不要将其与字符串 进行比较(因为'28-JUL-17'
是 字符串)并强制Oracle 执行隐式转换和花时间在nothing上。切换到
compensationdate BETWEEN date '2017-07-28' and date '2018-01-26'
【讨论】:
谢谢。这加快了 SELECT * 查询并将时间减少到 1 秒(从 5 秒)。但是我的 SELECT COUNT(1) 仍然需要时间(仍在运行).. 是的,我昨天晚些时候想到了它。是的,对于 2 亿条记录来说,这很重要。【参考方案2】:在 where 子句中包含 OR
CONDITION 会忽略查询中索引的使用。你应该摆脱 OR 条件。可以有多种方法。其中一种方法是——
SELECT /*+ parallel(sales 8)
index_ffs(sales ,sales_COMPDATE)
index_ffs(sales , sales_eventtypeseq )*/
COUNT(1)
FROM sales
WHERE processingunitseq=38
AND compensationdate BETWEEN TO_DATE('28-JUL-17') AND TO_DATE('26-JAN-18')
UNION ALL
SELECT /*+ parallel(sales 8)
index_ffs(sales ,sales_COMPDATE)
index_ffs(sales , sales_eventtypeseq )*/
COUNT(1)
FROM sales
WHERE processingunitseq=38
AND compensationdate NOT BETWEEN TO_DATE('28-JUL-17') AND TO_DATE('26-JAN-18') -- To avoid duplicates
AND eventtypeseq IN (1, 2, 3, 4);
其他建议,请贴出查询的执行计划。
【讨论】:
这将返回两行而不是一行,甚至可能读取整个表格两次。 这将读取表两次,但由于此查询将使用索引,因此执行速度会更快。具有 OR 条件根本不会使用 Index,并且性能会很差。 Oracle 可以使用带有OR
条件的索引。以上是关于即使使用 parallel(8) 提示,具有数百万条记录的表中的 Count(1) 也很慢的主要内容,如果未能解决你的问题,请参考以下文章
对于具有数百万像素的 2D 未装箱像素阵列,建议使用哪种 Haskell 表示?
如何使用 pandas 或 python 将具有数百万行的表从 PostgreSQL 复制到 Amazon Redshift