Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql查询执行时间比预期时间长_Sql - Fatal编程技术网

Sql查询执行时间比预期时间长

Sql查询执行时间比预期时间长,sql,Sql,我正在尝试执行下面的查询,但大约需要40分钟 select logentryid from ( select * from logentry_payloaddata pd, logentry le where ( pd.entryid=le.logentryid and le.eventdatetime=(trunc(sysdate) - 14) ) order by le.loge

我正在尝试执行下面的查询,但大约需要40分钟

select logentryid 
from (
     select * from logentry_payloaddata pd,
     logentry le
     where (
            pd.entryid=le.logentryid
       and
            le.eventdatetime=(trunc(sysdate) - 14)
     )
     order by le.logentryid asc
)
在表logentry中有4,24,91461条记录,在logentry有效载荷数据中有4,15,16346条记录(或在世界某些地区有“42491461”和“41516346”,甚至在其他一些地区有“42.491.461”和“41.516.346”——编辑)

在resp表中的logentryid和entryid上有索引

有人能建议在这种情况下该怎么办。

一些建议:

1-索引
eventdatetime
,如果尚未索引

2-为
(trunc(sysdate)-14)
定义一个变量-这将阻止函数为每一行运行,并允许使用步骤1中的索引

3-取消代码混淆。此处不需要嵌套,您使用的是老式的
JOIN
语法,这可能会导致问题:

SELECT logentryid 
FROM logentry_payloaddata pd
INNER JOIN logentry le
   ON pd.entryid=le.logentryid
WHERE le.eventdatetime = @MyDateVariable
ORDER BY logentryid ASC
尝试:

您可以将where子句放在内部联接上,以便更快地进行比较

如果多个客户端同时访问/更新您的数据库,那么尝试使用nolock也是值得的。请先阅读有关使用nolock的内容-在其他客户端执行提交之前,您会得到结果

SELECT
  le.logentryid
FROM
  logentry_payloaddata     pd
INNER JOIN
  logentry                 le
    ON pd.entryid=le.logentryid
WHERE
  le.eventdatetime = CAST(trunc(sysdate) - 14 AS DATETIME)
ORDER BY
  le.logentryid ASC
1) 。为了我的利益更改了布局(使用内部连接等),但怀疑它是否会改变性能

2) 。在日期比较中添加了一个
CAST()
。您的代码需要隐式的
CAST()
。使用显式的
CAST()。这非常重要,因为它决定了如何使用索引

3) 。索引-没有单一的答案,这取决于数据的统计数据

在表
logentry\u payloaddata
中,您肯定需要
entryid
上的索引

在表
logentry
中有两个不同的索引可能会有所帮助:
-
(logentryid,eventdatetime)

-
(eventdatetime,logentryid)


我最好的猜测是后者的表现最好。但我建议同时创建这两个,并检查实际使用的是哪一个。

在eventdatetime上创建索引?是eventdatetime筛选器导致了问题。我不确定这是什么RDBMS,但您可能无法使用索引,因为您正在与函数的输出进行比较。看起来像是不必要的嵌套选择。您可能会受益于仅使用le的最后14天作为子选择,然后将其加入到pd中。@Lamak:如果每个表中只有那么几条记录,我不认为查询可能需要40分钟。事实上,我认为这是印度常用的Lakh(参见此处:)。我将把这个问题编辑成好的‘ole’Merican。你基于什么“将where子句放在内部连接上以便更快地比较”?它将在所有版本的SQL Server中生成相同的执行计划,并混淆过滤器实际应用的位置。我认为这只适用于子查询。您是否同意布尔比较“pd.entryid=le.logentryid”与“le.eventdatetime=(trunc(sysdate)-14)”一样是一个过滤器,并且应该位于相同的位置(where子句或内部联接)。否,
pd.entryid=le.logentryid
是联接条件,并且
eventdatetime
筛选器应用于联接的结果集,并且应该位于where子句中。@user923721-SQL被编译为计划,而不是按“原样”执行。实际上,
JOIN
版本将产生相同的计划。在这种情况下,在
ON
子句和
WHERE
子句之间移动条件没有任何区别。您甚至可以在le.eventdatetime=(trunc(sysdate)-14)上加入
,并使用
进行过滤,其中pd.entryid=le.logentryid
,仍然可以得到相同的计划。SQL编译器并没有过于简单,这会让它们感到困惑。JNK这是一样的。“此联接的联接条件是id的匹配项和日期=whatever”“”联接条件可以同样为nothing(完全外部联接),然后应用id的匹配项和日期=whatever的筛选器。为什么建议使用该变量?什么环境会在每一行上重新计算这个标量常量?(除非您的意思是隐式强制转换可能会导致问题,在这种情况下,强制转换不仅仅是显式地强制转换标量常量?)非常感谢您的回答:-)
SELECT
  le.logentryid
FROM
  logentry_payloaddata     pd
INNER JOIN
  logentry                 le
    ON pd.entryid=le.logentryid
WHERE
  le.eventdatetime = CAST(trunc(sysdate) - 14 AS DATETIME)
ORDER BY
  le.logentryid ASC