Oracle 快速选择原因的方法
我有大约1000万条记录,它们的表结构是这样的Oracle 快速选择原因的方法,oracle,Oracle,我有大约1000万条记录,它们的表结构是这样的 ------------------------------------------- BARCODE | PRICE | BRAND ------------------------------------------- 1001001000111 | 1 USD | A 1001001000112 | 1 USD | B 1001001000113 | 1 USD | A 1001001000114 | 1 USD | B 100
-------------------------------------------
BARCODE | PRICE | BRAND
-------------------------------------------
1001001000111 | 1 USD | A
1001001000112 | 1 USD | B
1001001000113 | 1 USD | A
1001001000114 | 1 USD | B
1001001000115 | 1 USD | C
. . .
我想得到条码值,其中brand等于B;这是我的问题
SELECT BARCODE
FROM myTable
WHERE BRAND='B';
我花了很多时间等待结果,所以我尝试将Where
条件从Where BRAND='B'
更改为BRAND NOT IN('a','B','C',…)
。它似乎比('A'、'B'、'C'、…)中元素量的第一次查询要快。
很小,但只要('A'、'B'、'C'、'D'、…)中元素量越来越大,查询就会越来越慢
获取数据的最快方法是什么
请帮我解决这个问题。有多个问题需要解决
我有一张大桌子,大约有1000万张唱片
只要1000万行
就可以让你说这个表是巨大的?大小是多少?列数据类型是什么?我有一个包含50亿行的表
,我可以在几秒钟内选择所需的行。如何通过行数测量大小?当您谈论数据库中的大量数据时,请确保您提到的是数据的大小,而不是行数。1000万行可以是500KB
或1GB
回到要求上来,
我想得到条码值,其中brand等于B
Oracle optimizer足够聪明,可以决定是进行全表扫描还是使用索引。话虽如此,您必须收集最新的统计数据。此外,如果您计算出基数估计值,那么您实际上可以决定创建一个索引
基于有限的信息,我的建议是在品牌
列上创建一个索引
CREATE INDEX barcd_indx ON mytable(BRAND);
其中BRAND=B
为什么不在字符串文本周围使用单引号?应将字符串值括在单引号内:
WHERE BRAND='B';
有许多问题需要解决
我有一张大桌子,大约有1000万张唱片
只要1000万行
就可以让你说这个表是巨大的?大小是多少?列数据类型是什么?我有一个包含50亿行的表
,我可以在几秒钟内选择所需的行。如何通过行数测量大小?当您谈论数据库中的大量数据时,请确保您提到的是数据的大小,而不是行数。1000万行可以是500KB
或1GB
回到要求上来,
我想得到条码值,其中brand等于B
Oracle optimizer足够聪明,可以决定是进行全表扫描还是使用索引。话虽如此,您必须收集最新的统计数据。此外,如果您计算出基数估计值,那么您实际上可以决定创建一个索引
基于有限的信息,我的建议是在品牌
列上创建一个索引
CREATE INDEX barcd_indx ON mytable(BRAND);
其中BRAND=B
为什么不在字符串文本周围使用单引号?应将字符串值括在单引号内:
WHERE BRAND='B';
若并没有品牌索引,那个么你们最终会做一个完整的表格扫描
如果有一个关于品牌的索引,但是表的很大一部分是针对品牌B的,那么查询优化器可能会认为完整的表扫描仍然是最好的方法
如果brand上有一个索引,B是相当有选择性的,表示表中相对较小的部分,但优化器仍然选择进行完整表扫描,然后,您的统计数据可能会过时,您应该尝试在表上收集新的统计数据。如果没有品牌索引,那么您将最终执行完整的表扫描
如果有一个关于品牌的索引,但是表的很大一部分是针对品牌B的,那么查询优化器可能会认为完整的表扫描仍然是最好的方法
如果brand上有一个索引,并且B是相当有选择性的,表示表中相对较小的部分,但优化器仍然选择进行完整表扫描,那么您的统计数据可能已过时,您应该尝试在表中收集新的统计数据。首先检查硬件设置。这里我有一张和你的相似的桌子
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秒在我的桌面上,在生产数据库上,预期会有更好的结果 首先检查硬件设置。这里我有一张和你的相似的桌子
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秒在我的桌面上,在生产数据库上,预期会有更好的结果 选项1
根据品牌列对表进行分区。
如果品牌A、C的记录较少,则可以在一个分区中保存这些记录。
如果品牌B有更多记录,您可以为品牌B设置一个分区