PolarDB这个sql行存和列存性能差别好大 ,为什么? 行存24 rows in set (0.03 sec) 走列存 24 rows in set (4.32 sec)实例ID pc-j6c37gk49t0m93254
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):在这种模式下,数据按列进行存储。同一列的所有数据值存储在一起,这使得对于只查询少数几个字段的大规模数据分析操作非常高效。因为在这种情况下,只需要读取所需的列数据,而不是整个行,从而大大减少了数据读取量。
-
-
数据访问模式:
- 对于行存,当进行涉及多行但只查询少数字段的操作时,可能会加载大量不必要的数据,效率较低。
- 对于列存,由于同一列的数据连续存储,非常适合进行聚合分析和大数据扫描操作,比如排序、分组和统计等。列存可以高效地压缩和处理大量相同类型的数据,提高IO性能。
-
数据压缩:
- 列存由于同一列数据类型的相似性,往往能实现更高的数据压缩比,进一步减少存储空间和IO需求。
-
查询优化:
- 行存查询优化主要针对点查询和小范围的行扫描。
- 列存查询优化则更侧重于大规模数据分析和复杂的聚合操作。
以下为热心网友提供的参考意见
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索引选择优化器新特性”