【问题标题】:Complex query on big table大表上的复杂查询
【发布时间】:2014-10-10 23:01:58
【问题描述】:

我有一个大的用户表 (3M),结构:

age  (int) 
country (FK) 
city (text) 
gender (text) 
active (bool)

我的目标是搜索给定年龄区域、性别、城市和国家/地区的 15 位用户(偏爱活跃用户)。

由于表格的大小,我遇到了两个问题:

  • 即使有索引,也需要很长时间(几百 毫秒)

  • 每次运行查询时,结果都必须不同。目前我执行 使用 LIMIT 30 查询并从中获取随机 15 个结果,但是 30 个结果总是一样的。整张桌子太大而不能做 洗牌。

有克服类似问题的常用解决方案吗?

数据库服务器是 MySQL,在 Django 中实现。我也可以访问 Redis 缓存。

【问题讨论】:

  • 请发布您尝试执行的查询。另外,如果可能的话,发布explain select...的结果
  • 想一想,你可以使用不同偏移量的限制,第一次运行会前 15,下一次运行会给出 15-30 等的名称
  • 连同查询和explain select...,粘贴 CREATE TABLE 语句和所有关联的 CREATE INDEX 语句。

标签: mysql sql django performance


【解决方案1】:

您可以使用不同的限制和偏移量进行查询。 From the docs

您只需要跟踪您所在的位置。

# My example search criteria.
age = 21
gender = 'M'
city = 'Redmond'
country = 'US'

offset = 0
while True:
    next_fifteen = User.objects.filter(age=age,
                                       gender=gender,
                                       city=city,
                                       country=country)[offset:offset+15]
    if not next_fifteen.exists():
        break
    <do whatever>
    offset += 15

这将创建一个使用 OFFSET 45 LIMIT 15 的 SQL 语句

您可以看到做类似事情的网站。比如google搜索结果。转到第二页或第三页,您会注意到一个 url 参数&amp;start=60。并不是说我知道 google 的运作方式,但基本原理是一样的。

【讨论】:

  • 谢谢,这很有趣。但在这种情况下,例如。要获得第 150 个用户,我需要运行 10 次查询,对吗?
  • 这只是一个例子。如果你愿意,你可以做一个查询。 User.objects.filter(filterystuff=otherstuff)[150:165] 只是展示了如何使用偏移量来获取记录的子部分。您可以跟踪您的偏移量或提供连续的结果或......任何东西。
  • 我已经尝试过了,但是增加偏移量似乎会线性减慢查询速度,并且对于大约 200 的偏移量来说速度慢得让人无法接受
  • 当然可以。 LIMIT 需要收集与限制范围相等的记录数。限制为 15 可以获取 15 条记录,然后停止搜索。偏移量为 100 的限制为 15 必须首先获取 100 条记录,然后返回接下来的 15 条记录。不过,我不知道“不可接受的慢”是什么。听起来您可能需要花一些时间来构建数据库以提高与经常执行的特定查询相关的速度。也许这会有所帮助。 stackoverflow.com/questions/1243952/…
猜你喜欢
  • 2015-07-16
  • 2011-02-10
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 2012-09-06
  • 1970-01-01
相关资源
最近更新 更多