PolarDB这个sql行存和列存性能差别好大 ,为什么? 行存24 rows in set (0.03 sec) 走列存 24 rows in set (4.32 sec)
SELECT
sdt.produce_id,
sdt.customer_id,
sel.company_name AS company_name_m,
sel.prefix_domain_name,
sdt.products_id,
sdt.products_name_en,
sdt.products_url_name,
SUBSTR(sdt.category_id, 1, 3) AS category_id_lv1,
sdt.produce_cas_no AS cas_no,
sdt.produce_name,
sdt.produce_url_name,
sdt.goods_picture_s,
sdt.goods_picture_m AS goods_picture,
sdt.goods_picture_b,
sdt.complete_flag,
sdt.hot_flag,
sdt.main_flag,
sdt.grade_name,
sdt.content,
sdt.package_name,
sdt.n_price_type,
sdt.n_price_trade_term_type,
sdt.n_price_trade_term_text,
sdt.n_price,
sdt.n_price_unit,
sdt.n_price_currency,
sdt.n_price_currency_symbol,
CASE
WHEN CEILING(IFNULL(sdt.n_min_price, 0)) = 0 THEN '0'
WHEN sdt.n_price_end_date < CURRENT_DATE() THEN '0'
ELSE '1'
END AS n_pending_flag,
sdt.activity_id,
sdt.activity_type,
sdt.a_price_trade_term_type,
sdt.a_price_trade_term_text,
sdt.a_price,
sdt.a_price_unit,
sdt.a_price_currency,
sdt.a_price_currency_symbol,
sdt.n_price_loading_port_name,
sdt.brand_name,
CASE
WHEN IFNULL(sel.company_type, '') = '' THEN ''
ELSE CONCAT(
'typedefine.VERIFICATION_COMPANY_TYPE.',
sel.company_type
)
END AS company_type_m,
sel.country_name AS country_name_m
FROM
t_e_all_produce_v1 sdt STRAIGHT_JOIN t_e_all_seller_v1 sel ON sdt.customer_id = sel.customer_id
WHERE
sdt.customer_id = 'us20231121102443902'
AND sdt.delflag = '0'
AND sel.delflag = '0'
ORDER BY
sdt.complete_flag DESC,
sdt.main_flag DESC,
sdt.activity_id DESC,
sdt.hot_flag DESC,
sdt.produce_update_date DESC
LIMIT
1176, 24;
PolarDB的SQL行存和列存性能差别大的原因主要在于它们的数据存储方式和数据访问模式的不同:
数据存储方式:
行存储(Row-Oriented Storage):在这种模式下,数据以行的形式连续存储。每一行的所有字段值都存储在一起,这种方式非常适合于事务处理和点查询,因为这类查询通常需要访问表中的多个字段,而行存可以一次性加载整行数据,减少磁盘I/O操作。
列存储(Column-Oriented Storage):在这种模式下,数据按列进行存储。同一列的所有数据值存储在一起,这使得对于只查询少数几个字段的大规模数据分析操作非常高效。因为在这种情况下,只需要读取所需的列数据,而不是整个行,从而大大减少了数据读取量。
数据访问模式:
数据压缩:
查询优化:
PolarDB的行存和列存性能差别大,主要是由于它们在数据存储和处理方式上的不同特点所导致的。以下是一些可能影响性能的因素:
1、数据组织方式:行存和列存数据库采用不同的数据组织方式。行存按照行的方式组织数据,将每一行的数据都存储在一起,而列存则是按照列的方式组织数据,将每一列的数据存储在一起。这种数据组织方式的差异会导致在执行查询时,行存和列存的处理方式不同,进而影响性能。
2、数据压缩:列存通常具有更高的压缩率,因为它仅存储每个列的数据,而不是存储整个行的数据。因此,在处理大量数据时,列存可以减少存储空间的使用,从而降低I/O负载,提高性能。
3、计算优化:列存的计算优化更加高效。由于列存只需要处理查询所需的数据列,而不是整个数据行,因此可以显著减少计算量,提高查询处理速度。
4、并发控制:行存和列存在并发控制方面也存在差异。行存通常采用行级锁来控制并发操作,而列存则采用更加灵活的并发控制策略,以提高并发性能。
楼主你好,在您提供的SQL语句中,根据查询条件从t_e_all_produce_v1
表和t_e_all_seller_v1
表中获取数据,并进行排序和分页操作。
关于性能差异的原因可能是数据存储方式不同,因为行存和列存是不同的数据存储方式,行存适合于事务型的查询,而列存适合于分析型的查询。
还有就是数据分布方式不同,行存和列存在数据的分布方式上也有差异,行存将整行数据存储在一起,而列存将同一列的数据存储在一起。
这个是因为 ORDER BY LIMIT 的执行效率取决于数据分布和条件。在行存是按照顺序去扫描数据的,如果前面的数据满足条件的多就直接返回了,效率很高;如果满足条件的数据都在顺序的最末尾,就会执行很长时间。所以优化器估算的代价和实际执行的时间会有不准的情况
这个特定条件,你可以通过 HINT 去指定行存或者列存执行。后续8.0.2会针对这种场景发布动态执行的能力,能够自动解决这个问题 。HINT 列存执行:/+ SET_VAR(cost_threshold_for_imci=0) SET_VAR(imci_ap_threshold=0) /
HINT 行存执行:/+ SET_VAR(use_imci_engine=OFF) / 此回答整理自钉群“PolarDB 专家面对面 - 慢SQL索引选择优化器新特性”
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
PolarDB 分布式版 (PolarDB for Xscale,简称“PolarDB-X”) 是阿里云自主设计研发的高性能云原生分布式数据库产品,为用户提供高吞吐、大存储、低延时、易扩展和超高可用的云时代数据库服务。