Oracle SQL 优化:SQL 查询耗时很长
Posted
技术标签:
【中文标题】Oracle SQL 优化:SQL 查询耗时很长【英文标题】:Oracle SQL Optimization: SQL Query taking very long time 【发布时间】:2008-11-13 19:46:45 【问题描述】:SELECT DISTINCT
'LRS-TECH 1' || rpad(code,7) || rpad('APPTYPE',30) ||
rpad(licensing_no,30) || rpad(' ',300) AS RECORD
FROM APPS
WHERE L_code = '1000' AND licensing_no IS NOT NULL
这似乎是我无法在开发环境中将这些记录导出到文本文件的主要原因。有什么办法可以让这个查询运行得更快。它返回大约 2000 多行文本。
【问题讨论】:
通常索引在测试 NULL 时无济于事。 在检查 NOT NULLness 时会有所帮助 我建议你为查询制定一个执行计划并发布它,这样人们可以给你更好的响应。 根据我的经验,测试 NULL 等同于测试索引的 NULL。优化器足够聪明,知道这一点;并且根据经验,它不起作用。 oops - s/测试 NULLness/测试 NOT NULLness/ 【参考方案1】:解决方法很简单。
在 (code, license_no) 上创建索引并在 (l_code, license_no) 上创建索引以更快地获取记录。稍后在应用程序中执行“美化”部分,或者像这样简单地在外部包装器中执行:
SELECT 'LRS-TECH 1'
|| RPAD (code, 7)
|| RPAD ('APPTYPE', 30)
|| RPAD (licensing_no, 30)
|| RPAD (' ', 300) AS RECORD
FROM (SELECT DISTINCT code, licensing_no
FROM apps
WHERE l_code = '1000' AND licensing_no IS NOT NULL)
【讨论】:
【参考方案2】:除非您知道查询是如何被优化的,否则您无法诊断此问题。
试试这个:
explain plan for SELECT DISTINCT
'LRS-TECH 1' || rpad(code,7) || rpad('APPTYPE',30) ||
rpad(licensing_no,30) || rpad(' ',300) AS RECORD
FROM APPS
WHERE L_code = '1000' AND licensing_no IS NOT NULL
/
select * from table(dbms_xplan.display)
/
现在,也试试这个...它将帮助您检测统计问题:
explain plan for SELECT /*+ dynamic_sampling(4) */ DISTINCT
'LRS-TECH 1' || rpad(code,7) || rpad('APPTYPE',30) ||
rpad(licensing_no,30) || rpad(' ',300) AS RECORD
FROM APPS
WHERE L_code = '1000' AND licensing_no IS NOT NULL
/
select * from table(dbms_xplan.display)
/
请用这些结果更新您的原始帖子。
【讨论】:
【参考方案3】:如果您还没有 L_code 和 license_no 列的索引,我会尝试这样做。
【讨论】:
【参考方案4】:如果有很多 L_code = '1000' 的记录,并且唯一的附加测试是针对 NOT NULL,那么您可能遇到了基数问题。索引很难选择是否为 NULL。
返回的行数并不重要——问题在于检查的行数。
有哪些索引?
【讨论】:
【参考方案5】:嗯...摆脱 DISTINCT 可能有助于考虑到代码是 PRIMARY KEY。我不认为这是导致主要处理问题的原因。如果认为 RPAD 等导致大部分查询延迟。
索引主要是 ASCEND CODE 字段。这是表中唯一相关的索引。
【讨论】:
如果您认为是 RPAD,请尝试相同的查询,只需选择以下列:SELECT code、licensing_no WHERE L_code = '1000' AND license_no IS NOT NULL。我严重怀疑就是这样。【参考方案6】:您可以使用触发器和查询在辅助表、视图或列中预构建 RECORD 派生值,而不是在频繁查询表时即时构建它。
了解表格的大小可能会有所帮助。如果你有一个很大的列,或者很多记录,它可能与 IO 或缓存相关。
【讨论】:
【参考方案7】:对于所有查看此 SQL 的人,我很抱歉,但这是一个令人难以置信的服务器问题或其他问题。该场景似乎已经结束,我认为这是关于数据库所在位置的数据可用性问题,但有人可能能给我一些见解。
在我的本地主机上,我运行代码,立即运行。我在不到一秒的时间内将它提供给我的数据从数据表导出到文本文件……完成。
在我们的开发环境中,相同的页面在旧的 ASP 中。当我们转换为 .NET 时,我们的网站有一半是在经典的 ASP 中。问题似乎在于,在 DEV 站点上,经典的 ASP 页面运行完美,速度很快,不到一秒钟就完成了。当我上传新转换的 ASPX 文件时,它在该查询上挂起大约 30 秒。
在 Localhost 上,旧的经典 ASP 挂起大约 30 秒。
所以,我有一个反之亦然的问题,即经典 ASP 不会挂在 DEV 站点上,而是在我的机器上,而我自己的 ASPX 页面挂在 DEV 站点上,但不是在我的机器上。不同之处在于,我相信数据是从 DEV 站点上我自己的代码中提取的,而 ASP 页面是从驻留在旧的 DEV 站点服务器上的代码中提取数据的,该服务器将结果移植到 DEV 站点。因此,从技术上讲,代码不是在同一台服务器上运行的。经典的 ASP 代码在我们的旧站点服务器上。
我假设两个站点之间存在某种速度问题或服务器问题。
【讨论】:
查看两个环境的执行计划【参考方案8】:正如这里的大多数答案所表明的那样,您的问题听起来像是一个优化问题。您后来的回答显着改变了问题的性质。我建议将其作为新问题发布或修改原始问题以询问您真正想知道的内容。
我无法在 ASP/ASPX 问题上为您提供帮助,但如果这是一个优化问题,我建议为新的 WHERE 子句创建一个基于函数的索引,如下所示:
SELECT DISTINCT
'LRS-TECH 1' || rpad(code,7) || rpad('APPTYPE',30) ||
rpad(licensing_no,30) || rpad(' ',300) AS RECORD
FROM APPS
WHERE DECODE(L_code,'1000',licensing_no,NULL) IS NOT NULL;
基于函数的 DECODE(L_code,'1000',licensing_no,NULL) 索引将包含您要返回的所有记录。如果您需要更快的速度,您可以在查询结果上创建具体化视图,但这更像是最后的努力。
【讨论】:
【参考方案9】:我想知道这是否是因为 oracle 使用不同的索引(或根本不使用)从 aspx 页面进行查询。 我建议更新表格上的统计信息,看看是否有任何不同。 请参阅this question 了解如何操作(并且“计算统计信息”的 cmets 已过时,取而代之的是包)
【讨论】:
【参考方案10】:摆脱 DISTINCT。
【讨论】:
你假设他不想要 DISTINCT?以上是关于Oracle SQL 优化:SQL 查询耗时很长的主要内容,如果未能解决你的问题,请参考以下文章