我有一个非常大的表,有超过1000条记录和200列。当我尝试使用WHERE
语句检索匹配SELECT
子句中某些条件的记录时,需要花费很多时间。但大多数时候我只想选择一个与WHERE
子句中的条件匹配的记录而不是所有记录。
我想应该有一种方法可以选择一个记录并退出,这将最大限度地缩短检索时间。我在ROWNUM=1
子句中尝试了WHERE
,但它确实没有用,因为我猜即使找到符合WHERE
条件的第一条记录后,引擎仍会检查所有记录。如果我只想选择几条记录,是否有优化方法?
提前致谢。
修改
我正在使用oracle 10g。 查询看起来像,
Select *
from Really_Big_table
where column1 is NOT NULL
and column2 is NOT NULL
and rownum=1;
这似乎比没有rownum = 1;
的版本慢答案 0 :(得分:1)
rownum
是您想要的,但您需要将主查询作为子查询执行。
例如,如果您的原始查询是:
SELECT co1, col2
FROM table
WHERE condition
然后你应该尝试
SELECT *
FROM (
SELECT col1, col2
FROM table
WHERE condition
) WHERE rownum <= 1
有关rownum
如何在Oracle中运行的详细信息,请参阅http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html。
答案 1 :(得分:1)
1,000条记录不是表格中的大量数据。 200列是一个相当宽的表。出于这个原因,我建议你不要处理一个非常大的表 - 我已经对数百万行执行了查询而没有任何问题。
这是一个小实验......与“SELECT *”查询相比,运行此操作需要多长时间?
SELECT
Really_Big_table.Id
FROM
Really_Big_table
WHERE
column1 IS NOT NULL
AND
column2 IS NOT NULL
AND
rownum=1;
答案 2 :(得分:0)
在SQL中,大多数优化都会以表格上的索引形式出现(您可以将WHERE
和ORDER BY
列中显示的列编入索引作为粗略指南。
您没有指定您正在使用的SQL数据库,因此我无法指向一个好的资源。
Here是对Oracle索引的介绍。
Here另一个教程。
对于查询 - 您应始终指定要返回的列,而不是使用毯子*
。
答案 3 :(得分:0)
示例如下:您可以查看更多here
SELECT ename, sal
FROM ( SELECT ename, sal, RANK() OVER (ORDER BY sal DESC) sal_rank
FROM emp )
WHERE sal_rank <= 1;
您还必须对WHERE子句中的列进行一些列索引
答案 4 :(得分:0)
查询1000行表不应该花费很多时间。但也有例外情况,请检查您是否遇到以下情况之一:
这张桌子过去有很多行。由于高水位线( HWM )仍然很高(删除不会降低它)并且FULL TABLE SCAN
读取所有数据直到高水位线,可能需要很长时间即使表现在几乎为空,也返回结果。
分析您的表格(dbms_stats.gather_table_stats('<owner>','<table>')
)并将行实际使用的空间(磁盘空间)与有效空间(数据)进行比较,例如:
SELECT t.avg_row_len * t.num_rows data_bytes,
(t.blocks - t.empty_blocks) * ts.block_size bytes_used
FROM user_tables t
JOIN user_tablespaces ts ON t.tablespace_name = ts.tablespace_name
WHERE t.table_name = '<your_table>';
您必须考虑行和块的开销以及为更新保留的空间(PCT_FREE)。如果您发现使用的空间比需要的多得多(典型开销低于30%,YMMV),您可能需要重置HWM:
ALTER TABLE <your_table> MOVE;
然后重建INDEX(ALTER INDEX <index> REBUILD
),不要忘记之后收集统计数据。检查是否有数据类型为LOB,CLOB,LONG(irk)等的列。任何这些列中超过4000字节的数据都存储在行外(在单独的段中),这意味着如果不这样做选择这些列,您只需查询其他较小的列。
如果您遇到这种情况,请不要使用SELECT *
。要么您不需要大列中的数据,要么使用SELECT rowid
然后再进行第二次查询:SELECT * WHERE rowid = <rowid>
。