sql – 基于VARCHAR大小的Amazon Redshift查询性能不佳

前端之家收集整理的这篇文章主要介绍了sql – 基于VARCHAR大小的Amazon Redshift查询性能不佳前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在构建Amazon Redshift数据仓库,并根据VARCHAR列的已定义大小遇到意外的性能影响.细节如下.我的三个列显示在pg_table_def中:
schemaname | tablename |     column      |            type             | encoding  | distkey | sortkey | notnull 
------------+-----------+-----------------+-----------------------------+-----------+---------+---------+---------
 public     | logs      | log_timestamp   | timestamp without time zone | delta32k  | f       |       1 | t
 public     | logs      | event           | character varying(256)      | lzo       | f       |       0 | f
 public     | logs      | message         | character varying(65535)    | lzo       | f       |       0 | f

我最近运行了Vacuum and Analyze,我在数据库中有大约1亿行,而且根据我包含的列,我看到了非常不同的性能.

查询1:
例如,以下查询大约需要3秒钟:

select log_timestamp from logs order by log_timestamp desc limit 5;

查询2:
要求更多数据的类似查询在8秒内运行:

select log_timestamp,event from logs order by log_timestamp desc limit 5;

查询3:
但是,此查询与之前的查询非常相似,需要8分钟才能运行!

select log_timestamp,message from logs order by log_timestamp desc limit 5;

查询4:
最后,这个查询与慢速查询相同,但具有明确的范围限制,非常快(~3s):

select log_timestamp,message from logs where log_timestamp > '2014-06-18' order by log_timestamp desc limit 5;

消息列被定义为能够容纳更大的消息,但实际上它不包含太多数据:消息字段的平均长度是16个字符(std_dev 10).事件字段的平均长度是5个字符(std_dev 2).我能真正看到的唯一区别是VARCHAR字段的最大长度,但我认为这不应该对简单查询返回的时间产生一个数量级的影响!

任何见解将不胜感激.虽然这不是这个工具的典型用例(我们将聚合远远超过我们将检查单个日志),但我想了解我的表设计的任何微妙或不那么微妙的影响.

谢谢!

戴夫

解决方法

Redshift是一个“真正的柱状”数据库,只读取查询中指定的列.因此,当您指定2个小列时,只需要读取这两列.但是当你添加第3个大列时,Redshift必须做的工作会大大增加.

这与整行存储在一起的“行存储”数据库(sql Server,MysqL,Postgres等)非常不同.在行存储中添加/删除查询列在响应时间上没有太大区别,因为数据库无论如何都必须读取整行.

最后你的上次查询速度非常快的原因是因为你告诉Redshift它可以跳过很大一部分数据. Redshift将您的每一列存储在“块”中,并根据您指定的排序键对这些块进行排序. Redshift记录每个块的最小值/最大值,并可以跳过任何不能包含要返回的数据的块.

limit子句不会减少必须完成的工作,因为你告诉Redshift它必须首先按log_timestamp降序排序.问题是你的ORDER BY …在返回或丢弃任何数据之前,必须在整个潜在结果集上执行DESC.当列很小而且很快时,当它们很大时它很慢.

猜你在找的MsSQL相关文章