【问题标题】:Django: query set, multiple filters. Can i set the order in which the WHERE clause is formed so that it will help me in indexingDjango:查询集,多个过滤器。我可以设置 WHERE 子句的形成顺序,以便帮助我建立索引吗
【发布时间】:2020-12-02 19:03:55
【问题描述】:

我在 django 中有以下查询:

            end_date = timezone.now()
            start_date = end_date + timedelta(-5*365)
            queryset = (
                            DailyPriceHistory
                            .objects
                            .filter(symbol=symbol,datetime_utc__range=(start_date, end_date))
                            .order_by('datetime')
                            .order_by('creation_time')
                            .values_list('high','low','open','datetime','close','creation_time')
                        )

它生成的Sql是

SELECT `daily_price_history`.`high`,
       `daily_price_history`.`low`,
       `daily_price_history`.`open`,
       `daily_price_history`.`datetime`,
       `daily_price_history`.`close`,
       `daily_price_history`.`creation_time`
FROM `daily_price_history`
WHERE (`daily_price_history`.`datetime_utc`
        BETWEEN '2015-12-04 18:43:28.710229'
            AND '2020-12-02 18:43:28.710229'
        AND `daily_price_history`.`symbol` = 'A')
ORDER BY `daily_price_history`.`creation_time` ASC

目前我有 symboldatatime 作为单独的索引列

我找到了不遵循过滤器顺序的原因。即.filter(symbol=symbol,datetime_utc__range=(start_date, end_date))

我想要

WHERE (`daily_price_history`.`symbol` = 'A'
   AND `daily_price_history`.`datetime_utc`
      BETWEEN '2015-12-04 18:43:28.710229'
          AND '2020-12-02 18:43:28.710229')

但它使用

WHERE (`daily_price_history`.`datetime_utc`
           BETWEEN '2015-12-04 18:43:28.710229'
               AND '2020-12-02 18:43:28.710229'
           AND `daily_price_history`.`symbol` = 'A')

我也没有在 sql 中看到 order_by('datetime'),这是因为 datetime 已编入索引

【问题讨论】:

标签: mysql django


【解决方案1】:
WHERE (foo) AND (bar)

优化同

WHERE (bar) AND (foo)

但是,这些在不同的情况下很有用:

INDEX(a,b)
INDEX(b,a)

你需要

INDEX(symbol, datetime)

不管WHERE中的顺序如何。

但这很有效,因为

WHERE symbol = '...'        -- Equality test (put first in index)
  AND datetime BETWEEN ...  -- range test (put last in index)

无论索引如何,这都可能无法有效执行:

WHERE symbol IN (...)       -- IN() is harder than = to optimize
  AND datatime BETWEEN ...

【讨论】:

  • 你能看到我问过的类似问题吗,https://stackoverflow.com/questions/65150483/mysql-how-to-speed-up-an-sql-query-for-getting-data。在这里,我将 where 与 INgreater than 一起使用。 SO在这种情况下也会索引没有任何效率
  • 好的,这个问答讲的是=,那个讲的是IN。请注意,对于WHERE 中看似微小的差异,答案如何可能存在很大差异。好像我在另一个问答中回答了WHERE id > ...。涉及PARTITION 的答案可能对所有人来说都是最好的。
猜你喜欢
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多