3

我希望将约 10GB 的数据加载到内存中,并以以下形式对其执行 SQL:

  • 在单列(任何列)上排序
  • 在单个列(任何列)上聚合
  • 过滤单个列(任何列)

什么可能是性能的好选择?我遇到的一些可能可行的解决方案是TimesTenExtremeDBSQL In-memory,甚至是VaexCudf等数据帧。

我正在寻求优化查询时间——这就是我真正关心的。举个概念性的例子,想想一个 Excel 表格,用户可以在其中对任何列进行排序或过滤(应用程序不提前知道要“索引”哪些列,因为所有列都可能被使用)。


更新:我在下面发布我的熊猫基准。我知道 pandas 对此并不理想,但制作原型并获得基准数据非常棒:

文件(20M 行,1.2GB):https ://storage.googleapis.com/gcp-files/Sales20M.csv 。

  • 加载时间pd.read_csv):10.7s
  • 聚合: ( df.groupby('currency_code_id').count): 3.3s
  • 排序: ( df.sort_values('price')): 6.8s
  • 枢轴:( df.pivot_table(index='code',columns='territory_id', values='id', aggfunc=len, fill_value=0)):3.4 秒。

如果使用数据库,请不要创建索引,因为用例是我们不知道事先使用的列。(或者,我想你可以在每个字段上创建一个索引——但如果是这样,请在加载时包括所有这些索引的创建)。

哪个工具最适合这个?

4

5 回答 5

4

我猜您想要materialized一个随机数据文件并对其执行亚秒级查询,并且您已经准备好为此付出代价(因为内存中的功能通常是企业级的)。

例如SQL Server,有很多选项:

或者只是使用分区,或者 PostgreSQL 或 MongoDB 分片。此类技术的示例和演示显示了亚秒级性能……但这取决于具体情况,因为存在局限性。

例如:

  • 与传统索引相比,列存储索引在过滤和仅获取少量行时可能会出现问题
  • 内存中OLTP

在您的情况下,拥有 10 GB 的数据并希望获得良好的性能,您不需要做一些特别的事情。只需在插入之前分析和规范化数据并创建相应的索引。

Well begun is half done花一些时间以正确的方式写入数据将为您提供所需的性能。

例如:

  1. 在表格中插入数据文件

  2. 对于表中的每一列

    • 履行count distinct
    • 如果值小于count distinct / countX,则创建一个单独的包含列的表idvalue
    • 在其中插入不同的值
    • 向表中添加新列并在那里添加新的 id
    • 在该列上创建索引

减小表的大小将提高 IO 操作计数。按数字搜索和分组比按文本搜索和分组要快。

当然,您需要更改应用程序 - 不是按搜索some city name,而是按其过滤ID。在count每个城市之后countries ids,您将执行第二次查询以将它们转换idsnames.

我觉得在你的案例中应用一些基本原则会比使用一些高价和限制的高级技术更好,这在未来对应用程序提出新要求时可能至关重要。


在具有 8 GB RAM 和 4 个虚拟处理器的虚拟机上。不幸的是,它在 HDD 上,并且从这里开始的 I/O 非常糟糕。运行 SQL Server 2019 标准版。因此,由于硬件的原因,数据加载速度很慢。

  • 表2分钟(我是用SSMS接口导入数据的,如果用bcp会更好不过……毕竟是硬盘)
  • 1.5分钟为每个字段添加索引

因此,表格如下所示:

在此处输入图像描述

可见我有多懒。导致3.2为数据和索引分配 GB 的每个字段没有规范化和索引:

exec sp_spaceused 'dbo.Sales20M'

在此处输入图像描述

但是一些结果:

select count(*) , currency_code_id from dbo.Sales20M group by currency_code_id

当然,我们使用索引时为 0 秒:

在此处输入图像描述

select TOP 10 * from dbo.Sales20M   order by PRICE_IN_USD desc;

0 秒,但请注意我正在使用TOP- 基本上,当您进行排序时,您需要显示部分行,对吗?如果我出于某种原因对整行进行排序:

select  * 
INTO #X
from dbo.Sales20M   order by PRICE_IN_USD desc;

它运行 2 秒(我将数据插入表中,因为渲染也需要时间)。

至于PIVOT,它在 SQL Server 中不是很快,但R如果你需要大量的东西,你可以使用它。我不明白你的意思,但计算了美元的平均价格PIVOTCodeterritory_id

SELECT *
FROM 
( 
    SELECT Code
              ,territory_id
              ,AVG(price_in_usd) price_in_usd
    FROM dbo.Sales20M
    GROUP BY Code
            ,territory_id
)DS
PIVOT
(
    MAX(price_in_usd) FOR territory_id IN ([AE], [AG], [AI], [AL], [AM], [AO], [AR], [AT], [AU], [AW], [AZ], [BA], [BE], [BF], [BG], [BH], [BJ], [BM], [BN], [BO], [BR], [BS], [BW], [BY], [BZ], [CA], [CH], [CI], [CL], [CO], [CR], [CV], [CY], [CZ], [DE], [DK], [DM], [DO], [EC], [EE], [EG], [ES], [FI], [FJ], [FM], [FR], [GA], [GB], [GD], [GH], [GM], [GR], [GT], [GW], [HK], [HN], [HR], [HT], [HU], [ID], [IE], [IL], [IN], [IS], [IT], [JM], [JO], [JP], [KG], [KH], [KN], [KR], [KW], [KY], [KZ], [LA], [LB], [LK], [LT], [LU], [LV], [MD], [MK], [ML], [MN], [MO], [MT], [MU], [MX], [MY], [MZ], [NA], [NE], [NI], [NL], [NO], [NP], [NZ], [OM], [PA], [PE], [PG], [PH], [PL], [PT], [PY], [QA], [RU], [RW], [SA], [SE], [SG], [SI], [SK], [SN], [SV], [SZ], [TG], [TH], [TJ], [TM], [TR], [TT], [TW], [TZ], [UA], [UG], [US], [UY], [UZ], [VE], [VG], [VN], [ZA], [ZM], [ZW])
) PVT;

我又懒了,不使用动态 PIVOT。需要0-1秒。

在此处输入图像描述


结论:

我的观点是,即使我的设置很糟糕,而且我非常懒惰,因为没有花时间规范数据和创建正确的索引,我仍然接近 0 秒的结果。你可以简单地从像 PostgreSQL 这样的免费东西开始,我相信你会得到很好的结果。当然,如果您需要它们以优化特定用例,“花哨”的东西总是在那里。

于 2020-07-24T09:06:40.973 回答
3

我用带有 20M 记录的 csv 构建了一个真实的测试用例。为了我的概念证明,我将比较 Oracle 中的两个选项。Oracle 内存选项与 Oracle 并行查询。我们的想法是查看结果是否符合您的期望。

  • In Memory Option 是许可费,因此您必须支付额外费用
  • 并行查询是 Oracle 数据库企业版中包含的一项功能。

实验室:Linux Red Hat 7 服务器:16 个 CPU 和 32 GB RAM 内存部分 = VMware 上使用 IBM ESX 硬件系列的 4GB VM 虚拟服务器

测试用例的元素

SQL> create tablespace tbtest datafile '/bbdd_odcgrc1r/datos/test.dbf' size 2g autoextend on next 100m maxsize 10g ;

Tablespace created.

SQL> create user test_perf identified by "Oracle_1" ;

User created.

SQL> grant connect to test_perf ;

Grant succeeded.

SQL> grant create table to test_perf ;

Grant succeeded.

SQL> alter user test_perf quota unlimited on tbtest ;

User altered.

SQL>

没有内存选项的 Oracle 并行查询

我使用直接路径 sql loader 加载了 csv 文件:

Table TEST_PERFORMANCE:
  20000000 Rows successfully loaded.
  0 Rows not loaded due to data errors.
  0 Rows not loaded because all WHEN clauses were failed.
  0 Rows not loaded because all fields were null.

Bind array size not used in direct path.
Column array  rows :    5000
Stream buffer bytes:  256000
Read   buffer bytes: 1048576

Total logical records skipped:          1
Total logical records read:      20000000
Total logical records rejected:         0
Total logical records discarded:        0
Total stream buffers loaded by SQL*Loader main thread:     4112
Total stream buffers loaded by SQL*Loader load thread:        0

Run began on Sat Jul 25 00:57:23 2020
Run ended on Sat Jul 25 00:57:34 2020

显然,将文件加载到数据库中与在 panda 中加载文件(根本不一样)。因为 Panda 不需要将数据加载到任何东西(在本例中为数据库数据文件)

SQL> desc test_perf.test_performance
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 DATE_ID                                            DATE
 INSTANCE_ID                                        NUMBER
 TERRITORY_ID                                       VARCHAR2(10 CHAR)
 CODE                                               VARCHAR2(10 CHAR)
 PRICE                                              NUMBER
 CURRENCY_CODE_ID                                   VARCHAR2(10 CHAR)
 PRICE_IN_USD                                       NUMBER

我收集表的统计信息,现在让我们看看它的行为

SQL> exec dbms_stats.gather_table_stats ( 'TEST_PERF' , 'TEST_PERFORMANCE' , block_sample => true );

PL/SQL procedure successfully completed.

按currency_code_id分组(不排序)

SQL> select count(*) , currency_code_id from test_perf.test_performance group by currency_code_id
90 rows selected.

Elapsed: 00:00:00.35

按 currency_code_id 分组,但按计数器排序

SQL>  select count(*) , currency_code_id from test_perf.test_performance group by currency_code_id order by count(*) desc ;

90 rows selected.

Elapsed: 00:00:00.70

对所有记录进行排序并通过 sqlplus 显示它们仅用于创建输出就消耗大量时间,但查询本身非常快

SQL> select * from test_perf.test_performance order by PRICE_IN_USD desc ;

20000000 rows selected.

Elapsed: 00:01:31.48

Execution Plan
----------------------------------------------------------
Plan hash value: 1897103579

---------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name             | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                  |    20M|   972M|       |  5940   (1)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR         |                  |       |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (ORDER)    | :TQ10001         |    20M|   972M|       |  5940   (1)| 00:00:01 |  Q1,01 | P->S | QC (ORDER) |
|   3 |    SORT ORDER BY        |                  |    20M|   972M|  1376M|  5940   (1)| 00:00:01 |  Q1,01 | PCWP |            |
|   4 |     PX RECEIVE          |                  |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,01 | PCWP |            |
|   5 |      PX SEND RANGE      | :TQ10000         |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,00 | P->P | RANGE      |
|   6 |       PX BLOCK ITERATOR |                  |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,00 | PCWC |            |
|   7 |        TABLE ACCESS FULL| TEST_PERFORMANCE |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------------

Note
-----
   - Degree of Parallelism is 32 because of table property


Statistics
----------------------------------------------------------
        364  recursive calls
          3  db block gets
      36963  consistent gets
      45558  physical reads
       2860  redo size
  703698256  bytes sent via SQL*Net to client
   14667271  bytes received via SQL*Net from client
    1333335  SQL*Net roundtrips to/from client
         64  sorts (memory)
          1  sorts (disk)
   20000000  rows processed

查询本身消耗的实时时间是

SQL> select * from test_perf.test_performance order by PRICE_IN_USD desc ;
Elapsed: 00:00:02.03

Execution Plan
----------------------------------------------------------
Plan hash value: 1897103579

---------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name             | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                  |    20M|   972M|       |  5940   (1)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR         |                  |       |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (ORDER)    | :TQ10001         |    20M|   972M|       |  5940   (1)| 00:00:01 |  Q1,01 | P->S | QC (ORDER) |
|   3 |    SORT ORDER BY        |                  |    20M|   972M|  1376M|  5940   (1)| 00:00:01 |  Q1,01 | PCWP |            |
|   4 |     PX RECEIVE          |                  |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,01 | PCWP |            |
|   5 |      PX SEND RANGE      | :TQ10000         |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,00 | P->P | RANGE      |
|   6 |       PX BLOCK ITERATOR |                  |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,00 | PCWC |            |
|   7 |        TABLE ACCESS FULL| TEST_PERFORMANCE |    20M|   972M|       |   435   (1)| 00:00:01 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------------

Note
-----
   - Degree of Parallelism is 32 because of table property

选择表的不同区域id

SQL> select distinct territory_id from test_perf.test_performance order by territory_id desc ;

136 rows selected.

Elapsed: 00:00:00.58

对于支点,我选择了这个简单的例子

SQL> select * from test_perf.test_performance
pivot ( count(*) for TERRITORY_ID in 
(
'ZW',
'ZM',
'ZA',
'VN',
'VG',
'VE',
'UZ',
'UY',
'US',
'UG',
'UA',
'TZ',
'TW',
'TT',
'TR',
'TM',
'TJ',
'TH',
'TG',
'SZ',
'SV',
'SN',
'SK',
'SI',
'SG',
'SE',
'SA',
'RW',
'RU',
'QA',
'PY',
'PT',
'PL',
'PH',
'PG',
'PE',
'PA',
'OM',
'NZ',
'NP',
'NO',
'NL',
'NI',
'NE',
'NA',
'MZ',
'MY',
'MX',
'MU',
'MT',
'MO',
'MN',
'ML',
'MK',
'MD',
'LV',
'LU',
'LT',
'LK',
'LB',
'LA',
'KZ',
'KY',
'KW',
'KR',
'KN',
'KH',
'KG',
'JP',
'JO',
'JM',
'IT',
'IS',
'IN',
'IL',
'IE',
'ID',
'HU',
'HT',
'HR',
'HN',
'HK',
'GW',
'GT',
'GR',
'GM',
'GH',
'GD',
'GB',
'GA',
'FR',
'FM',
'FJ',
'FI',
'ES',
'EG',
'EE',
'EC',
'DO',
'DM',
'DK',
'DE',
'CZ',
'CY',
'CV',
'CR',
'CO',
'CL',
'CI',
'CH',
'CA',
'BZ',
'BY',
'BW',
'BS',
'BR',
'BO',
'BN',
'BM',
'BJ',
'BH',
'BG',
'BF',
'BE',
'BA',
'AZ',
'AW',
'AU',
'AT',
'AR',
'AO',
'AM',
'AL',
'AI',
'AG',
'AE'
) ) 
 order by id 

Elapsed: 00:00:04.74

Oracle 内存选项

我配置了一个 4GB 的 In memory 区域,并没有那么多。

Total System Global Area 1.2885E+10 bytes
Fixed Size                 12192520 bytes
Variable Size            5184161016 bytes
Database Buffers         3388997632 bytes
Redo Buffers                4583424 bytes
In-Memory Area           4294967296 bytes
Database mounted.
Database opened.
SQL> SHOW PARAMETER INMEMORY

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
inmemory_adg_enabled                 boolean     TRUE
inmemory_clause_default              string
inmemory_expressions_usage           string      ENABLE
inmemory_force                       string      DEFAULT
inmemory_max_populate_servers        integer     8
inmemory_query                       string      ENABLE
inmemory_size                        big integer 4G
inmemory_trickle_repopulate_servers_ integer     1
percent
inmemory_virtual_columns             string      MANUAL
optimizer_inmemory_aware             boolean     TRUE

SQL> ALTER TABLE TEST_PERF.TEST_PERFORMANCE INMEMORY PRIORITY HIGH;

Table altered.

SQL> select segment_name
,    partition_name
  2    3  ,    inmemory_size / 1024 / 1024 as inmemory_size_mb
,    bytes / 1024 / 1024 as bytes_mb
,    populate_status
  4    5    6  ,    trunc(bytes / inmemory_size, 1) * 100 as compression_ratio
from v$im_segments
  7    8  order by segment_name, partition_name;

SEGMENT_NAME
--------------------------------------------------------------------------------
PARTITION_NAME
--------------------------------------------------------------------------------
INMEMORY_SIZE_MB   BYTES_MB POPULATE_STAT COMPRESSION_RATIO
---------------- ---------- ------------- -----------------
TEST_PERFORMANCE

          362.25 514.046875 COMPLETED                   140

SQL> select count(*),length(date_id) from test_perf.test_performance group by length(date_id)

Execution Plan
----------------------------------------------------------
Plan hash value: 3227171220

-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                  |    11 |   121 |    29  (59)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR                   |                  |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)             | :TQ10001         |    11 |   121 |    29  (59)| 00:00:01 |  Q1,01 | P->S | QC (RAND)  |
|   3 |    HASH GROUP BY                  |                  |    11 |   121 |    29  (59)| 00:00:01 |  Q1,01 | PCWP |            |
|   4 |     PX RECEIVE                    |                  |    11 |   121 |    29  (59)| 00:00:01 |  Q1,01 | PCWP |            |
|   5 |      PX SEND HASH                 | :TQ10000         |    11 |   121 |    29  (59)| 00:00:01 |  Q1,00 | P->P | HASH       |
|   6 |       HASH GROUP BY               |                  |    11 |   121 |    29  (59)| 00:00:01 |  Q1,00 | PCWP |            |
|   7 |        PX BLOCK ITERATOR          |                  |    20M|   209M|    14  (15)| 00:00:01 |  Q1,00 | PCWC |            |
|   8 |         TABLE ACCESS INMEMORY FULL| TEST_PERFORMANCE |    20M|   209M|    14  (15)| 00:00:01 |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------------------------------------------------------------

Note
-----
   - Degree of Parallelism is 32 because of table property

让我们测试一些查询。

按地区分组

SQL> select count(*),TERRITORY_ID from test_perf.test_performance group by TERRITORY_ID ;

136 rows selected.

Elapsed: 00:00:00.24

按 instance_id 分组

SQL> select count(*) , INSTANCE_ID from test_perf.test_performance group by INSTANCE_ID

11251 rows selected.

Elapsed: 00:00:00.27

按 2 个字段分组

SQL> select count(*), instance_id, territory_id from test_perf.test_performance group by instance_id, territory_id ;

278269 rows selected.

Elapsed: 00:00:00.84

如您所见,显然当我在内存中有一张表时,这些操作的性能会提高,但如果您开始对查询应用分析,您会注意到更多改进。

几个统计功能和分组依据

SQL> select territory_id,sum(to_number(price)),avg(to_number(price)),max(to_number(price)),min(to_number(price))
  2  from test_perf.test_performance group by territory_id ;

Elapsed: 00:00:00.57

但是,PIVOT 对于内存来说通常不是一个好主意,因为表使用了列存储。

The same query with pivot executed before takes 

    Elapsed: 00:00:15.93

正如您在上面的示例中所看到的,我没有更改表的 PARALLEL 属性,所以让我向您展示当没有为具有 INMEMORY 选项的对象启用并行时查询的行为

SQL> alter table test_perf.TEST_PERFORMANCE noparallel ;

Table altered.

SQL> select count(*) , currency_code_id from test_perf.test_performance group by currency_code_id
  2  ;

90 rows selected.

Elapsed: 00:00:02.14

Execution Plan
----------------------------------------------------------
Plan hash value: 151279035

------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                  |    90 |   450 |   909  (62)| 00:00:01 |
|   1 |  HASH GROUP BY              |                  |    90 |   450 |   909  (62)| 00:00:01 |
|   2 |   TABLE ACCESS INMEMORY FULL| TEST_PERFORMANCE |    20M|    95M|   411  (16)| 00:00:01 |
------------------------------------------------------------------------------------------------

IMPQ

对于最后一部分,我保留了所有选项中最好的一个,即并行和内存的组合,称为 IMPQ 或内存并行查询。此功能提供了两全其美的效果,为了启动,您必须为您的表启用并行,将表放在内存区域并将参数 PARALLEL_DEGREE_POLICY 定义为 AUTO。

这方面的一个例子是

SQL> alter session set parallel_degree_policy=auto ;

Session altered.

SQL> set autotrace traceonly explain
SQL> select count(*),territory_id from test_perf.test_performance group by territory_id

Execution Plan
----------------------------------------------------------
Plan hash value: 3227171220

-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                  |   136 |   408 |    78  (59)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR                   |                  |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)             | :TQ10001         |   136 |   408 |    78  (59)| 00:00:01 |  Q1,01 | P->S | QC (RAND)  |
|   3 |    HASH GROUP BY                  |                  |   136 |   408 |    78  (59)| 00:00:01 |  Q1,01 | PCWP |            |
|   4 |     PX RECEIVE                    |                  |   136 |   408 |    78  (59)| 00:00:01 |  Q1,01 | PCWP |            |
|   5 |      PX SEND HASH                 | :TQ10000         |   136 |   408 |    78  (59)| 00:00:01 |  Q1,00 | P->P | HASH       |
|   6 |       HASH GROUP BY               |                  |   136 |   408 |    78  (59)| 00:00:01 |  Q1,00 | PCWP |            |
|   7 |        PX BLOCK ITERATOR          |                  |    20M|    57M|    38  (16)| 00:00:01 |  Q1,00 | PCWC |            |
|   8 |         TABLE ACCESS INMEMORY FULL| TEST_PERFORMANCE |    20M|    57M|    38  (16)| 00:00:01 |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------------------------------------------------------------

Note
-----
   - automatic DOP: Computed Degree of Parallelism is 12

在上面的语句中检查 DOP 从 32 到 12 的变化。这表明 IMPQ 已经确定该语句的最佳度数是 12,而不是由 CPU_COUNT * 2 派生的 32(因为该表是使用默认度数创建的自动的 )。

下面的这个查询现在使用 IMPQ 只需 0.14 秒,而不是 0.35 秒。

SQL> select count(*),territory_id from test_perf.test_performance group by territory_id
  2  ;

136 rows selected.

Elapsed: 00:00:00.14

这个其他查询现在需要 0.14 秒,而之前需要 0.70 秒

SQL> select count(*) , currency_code_id from test_perf.test_performance group by currency_code_id order by count(*) desc ;

90 rows selected.

Elapsed: 00:00:00.14

概括

如果您需要的时间少于一秒,并且您主要使用分析,那么 Oracle 内存选项可能是一个好主意。如果是这种情况,您可能还希望启用 IMPQ 以获得最佳结果。关于应该或不包含哪些列、如何将表填充到内存区域等方面需要做一些工作。分析的复杂性越大,您会注意到的性能就越好。

不过,如果您可以忍受 1 到 5 秒之间的时间,那么没有索引的并行查询可能是一种免费且易于配置的解决方案。

随意评论任何内容或要求对测试用例进行任何澄清。

于 2020-07-25T00:38:38.527 回答
1

如果有用,这些是我使用 cuDF 在 32GB V100 上读取、聚合和排序文件时得到的一些快速比较。对于 SQL,您可能需要查看BlazingSQL

粗略地与我机器上的 pandas 相比,读取这个文件的速度大约快 20 倍,聚合大约快 150 倍,排序大约快 50 倍。请注意,对 cuDF 的支持pivot尚不可用,因此不包括在下面。

import cudf
​
cudf.set_allocator(
    pool=True, # half the GPU by default
)
​
%time df = cudf.read_csv("Sales20M.csv")
%time x = df.groupby('currency_code_id').count()
%time x = df.sort_values('price')
CPU times: user 402 ms, sys: 157 ms, total: 559 ms
Wall time: 557 ms
CPU times: user 17.1 ms, sys: 8.97 ms, total: 26.1 ms
Wall time: 25.8 ms
CPU times: user 96.2 ms, sys: 32 ms, total: 128 ms
Wall time: 128 ms
import pandas as pd
​
%time df = pd.read_csv("Sales20M.csv")
%time x = df.groupby('currency_code_id').count()
%time x = df.sort_values('price')
CPU times: user 8.23 s, sys: 1.67 s, total: 9.9 s
Wall time: 9.89 s
CPU times: user 3.32 s, sys: 355 ms, total: 3.68 s
Wall time: 3.67 s
CPU times: user 5.77 s, sys: 586 ms, total: 6.35 s
Wall time: 6.35 s
于 2020-07-24T14:07:11.617 回答
0

查询调优的一个重要部分是了解优化器可用于处理各种查询构造的算法,例如,

  1. 过滤,
  2. 加入,
  3. 分组
  4. 聚合
  5. 它们如何扩展。

这些知识有助于为查询准备最佳物理环境,例如

一个。创建正确的索引
B. 根据您对优化器应从一种算法切换到另一种算法的阈值的熟悉程度,它还可以帮助您直观地了解在特定情况下应该在计划中看到哪种算法。

在调整性能不佳的查询时,您可以更轻松地在查询计划中发现优化器可能做出次优选择的区域,例如由于基数估计不准确,并采取措施解决这些问题。

查询调优的另一个重要部分是开箱即用——超越优化器在使用显而易见的工具时可用的算法。要有创意。假设您有一个查询性能很差,即使您安排了最佳物理环境。对于您使用的查询构造,优化器可用的算法是 x、y 和 z,优化器会根据情况选择最好的算法。尽管如此,查询还是很糟糕。你能想象一个理论上的计划,它的算法可以产生更好的查询吗?如果您能想象到,您很可能可以通过一些查询重写来实现它,也许该任务的查询构造不太明显。

欲了解更多信息,请点击以下链接。

专业人士

于 2020-07-28T10:10:22.877 回答
0

可以使用 Oracle TimesTen In-Memory Database,但 Oracle Database 的 Oracle In-Memory 特性更适合这种类型的工作负载。

TimesTen 更多地为低延迟/高吞吐量 ACID 事务和分析类型查询而设计

于 2020-10-16T20:08:09.947 回答