我有大约1000万条记录,其表格结构如下
-------------------------------------------
BARCODE | PRICE | BRAND
-------------------------------------------
1001001000111 | 1 USD | A
1001001000112 | 1 USD | B
1001001000113 | 1 USD | A
1001001000114 | 1 USD | B
1001001000115 | 1 USD | C
. . .
我想获得品牌等于B的条形码值;这是我的疑问。
SELECT BARCODE
FROM myTable
WHERE BRAND='B';
我花了很多时间等待结果,所以我尝试将Where
条件从Where BRAND='B'
更改为BRAND NOT IN ('A','B','C',..)
。它似乎比第一个查询更快,元素in ('A','B','C',..)
的数量很小,但只要元素in ('A','B','C','D',...)
的数量变得越来越大,查询就越来越慢。
获取数据的最快方法是什么?
请帮我解决这个问题。
答案 0 :(得分:0)
有许多问题需要解决。
我有大约1000万条记录的巨大表格
只有10 million
行会让您说该表格巨大?什么是尺寸?列数据类型是什么?我有一个5 billion rows
的表,我可以在几秒钟内选择我想要的行。如何根据行数测量大小?当您谈论数据库中的大量数据时,请确保提及数据的大小而不是行数。 1000万行可以是500KB
或1GB
。
回到要求,
我想获得品牌等于B的条形码值
Oracle优化器非常聪明,可以决定是进行全表扫描还是使用 INDEX 。话虽如此,您必须收集最新的统计信息。另外,如果您算出基数估算值,那么您实际上可以决定创建索引。
根据有限的信息,我的建议是在BRAND
列上创建一个索引。
CREATE INDEX barcd_indx ON mytable(BRAND);
BRAND = B;
为什么不会在字符串文字周围使用 单引号?您应该将字符串值括在单引号中:
WHERE BRAND='B';
答案 1 :(得分:0)
如果Brand上没有索引,那么您将最终进行全表扫描。
如果Brand上有索引,但该表的很大一部分是针对品牌B的,则查询优化器可能会认为全表扫描仍然是最好的方法。
如果品牌上有索引,并且B相当有选择性地代表表格的一小部分,但优化程序仍然选择进行全表扫描,那么您的统计数据可能是陈旧的,您应该尝试收集新的桌上的统计数据。
答案 2 :(得分:0)
首先检查您的硬件设置。在这里,我有一张与你相似的表
SQL> select count(*), count(distinct brand) from my10m;
COUNT(*) COUNT(DISTINCTBRAND)
---------- --------------------
10000000 19
SQL> select round(BYTES/(1024*1024)) MB from dba_segments where segment_name = 'MY10M';
MB
----------
296
启动SQL * Plus并检查扫描表所需的时间
SQL> set timi on;
SQL> set autotrace traceonly
SQL> set array 5000
SQL> select * from my10m;
10000000 rows selected.
Elapsed: 00:00:10.10
Execution Plan
----------------------------------------------------------
Plan hash value: 2382977685
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10M| 316M| 10314 (1)| 00:02:04 |
| 1 | TABLE ACCESS FULL| MY10M | 10M| 316M| 10314 (1)| 00:02:04 |
---------------------------------------------------------------------------
所以,在我的情况下,完全扫描表需要10秒钟。这是一个简单的基准,所以
具有过滤条件的查询不应该比这更糟糕。
运行此基准测试并将经过的时间与您的查询进行比较。
另请注意,我将ARRAYSIZE设置为5000,这可以减少网络往返次数,并可以加快查询速度。你不会说你如何访问 日期,但很可能你也可能增加获取大小。
注意 - 10秒在我的桌面上,在生产数据库上预期会有更好的结果。
答案 3 :(得分:0)
选项1
根据品牌栏对表格进行分区。 如果说品牌A,C的记录较少,您可以将它们放在一个分区中。 如果品牌B有更多记录,您可以为该特定品牌设置一个分区。
选项2
您还可以考虑在列品牌上创建位图索引。