包加入查询需要花费太多时间

时间:2017-02-17 06:08:48

标签: java database caching memcached cratedb

预要求:我需要在一个超过40K结果的查询中找到所有匹配结果。

要求:两个表 - product和product_category。我正在尝试从product_category表中获取具有匹配类别的所有产品。

表格结构:

CREATE TABLE catalog.product (
    product_id string PRIMARY KEY index using plain,
    name string,
    sku string,
) clustered by (product_id) into 4 shards;

create table catalog.product_category (
    category_id string primary key index using plain,
    product_id  string primary key index using plain,
    INDEX product_category_index using plain(product_id, category_id)
    active boolean,
    parent_category_id integer,
    updated_at timestamp
);

加入查询:

select p.product_id from catalog.product_category pc join catalog.product p on p.product_id=pc.product_id limit 40000;

尝试了多项内容 - 索引product_id(包括整数和字符串)等。

结果:要显示35K结果,每次花费超过90秒。

问题:如何优化查询响应时间?

其他一些信息:   - CPU核心-4   - 尝试使用一个或多个节点   - 默认分片   - 产品总数--35K和product_category仅有35K个企业。

用例:我正在尝试将crateDB用作持久缓存,但是在给定的查询响应时间内,我们无法做到这一点。所以我们将迁移到一些内存数据库,如REDIS或Memcache。选择crateDB的原因是对持久数据的查询能力。

1 个答案:

答案 0 :(得分:0)

与加入STRING类型相比,加入NUMERIC类型列非常昂贵(字符串值的相等性检查比数值更昂贵)。如果您没有特殊原因,我建议您将其更改为NUMERIC类型(例如INTEGERLONG,...),这将通过多重因素提高查询速度。

顺便说一下。 index using plain是所有列的默认索引设置,因此您可以将其保留。 此外,复合索引product_category_index无助于改进连接查询,如果您使用包含此索引列的WHERE子句对其进行过滤,这一点非常重要。

更新

您可以做的另一项改进是添加ORDER BY p.product_id, pc.product_id子句。这样,联接算法可能会在到达您应用的LIMIT时停止。