【问题标题】:How to optimize sql query? Seems distinct is very slow?如何优化sql查询?好像分明很慢?
【发布时间】:2012-03-05 21:08:43
【问题描述】:

我不是数据库专家,所以问题 =)

如何优化:

select count(DISTINCT userid) 
from users 
where date_trunc('month',login_date)=date_trunc('month','2012-01-12'::date)

表格行数少于 150 万。我在 login_date 上有一个索引,尽管查询执行时间与没有它时相同。字段 userid 也是主键。

在服务器机器上,这个查询需要超过 2000 毫秒。第一个可以帮助发挥最佳性能的人将获得声誉++:D

----------------a'b'c'd'e'f'g'h' 解决方案-------------- --------------------

CREATE OR REPLACE FUNCTION my_date_trunc_month(some_date DATE) 
  RETURNS DATE 
AS $$
BEGIN
   return date_trunc('month',$1);
END;
$$LANGUAGE plpgsql
IMMUTABLE;


CREATE INDEX computedIdx ON gameuser_daily_activity (my_date_trunc_month(login_date));

select count(DISTINCT gameuser_fk) from gameuser_daily_activity where my_date_trunc_month(login_date)=my_date_trunc_month('2012-01-12'::date)

并且需要 110 毫秒 :)

【问题讨论】:

    标签: sql postgresql optimization


    【解决方案1】:

    定义这个索引:

    CREATE INDEX computedIdx ON users (date_trunc('month',login_date))

    【讨论】:

    • 嗯,错误:索引表达式中的函数必须标记为 IMMUTABLE
    • stackoverflow.com/questions/5973030/… - 创建一个标记为不可变的函数来转换日期。
    • 谢谢。优化到 110 毫秒!如果存在没有自定义函数的解决方案,将等待 =)
    • 或者说date_trunc('month',login_date::timestamp)
    【解决方案2】:

    如果 UserID 是主键,它将是不同的,您不需要在其中添加不同的.. http://www.w3schools.com/sql/sql_primarykey.asp

    并且首选基于主键的聚集索引

    【讨论】:

    • 抱歉,PK 在两个字段中(用户 ID、登录日期)
    • 好的,所以它是一个复合主键.. 其中 date_trunc('month',login_date)='01' 可以提高性能一点点,而 UserID 应该是主键,它将在许多其他方面为您提供帮助案例也
    • 其实表名是user_daily_activity。我将它重命名为用户,现在我知道我不应该那样做。复合键是必要的
    • Ohkk 那么你能做的最好的事情就是在 UserID 上创建一个聚集索引
    【解决方案3】:

    你能试试这样的吗?

    select count(DISTINCT userid) 
    from users 
    where 
    login_date >= '2012-01-12'::date and 
    login_date < '2012-01-12'::date + '1month'::interval
    

    删除索引列周围的表达式将使优化器的工作更容易。

    【讨论】:

    • 当然你需要一个 login_date 的索引才能生效。
    • 我不是 Postgresql 专家,您必须处理日期范围。问题是:不要在索引列周围放置表达式,以便优化器明确提示您要使用该索引。
    猜你喜欢
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多