【问题标题】:Split MySQL table into 2? Current search is too slow将 MySQL 表拆分为 2?当前搜索太慢
【发布时间】:2012-02-09 02:29:38
【问题描述】:

我正在使用 MySQL 表将事物的数据存储在用户将搜索的地图上。该网站允许用户添加额外的过滤器来缩小他的结果。

主 MySQL 查询:

SELECT listing_id, listings.property_1, property_2, address_1, address_2, city, listings.lat, listings.lng, img_subpath, photos, some_timestamp
    FROM table
    WHERE listings.lat BETWEEN 61.123 AND 61.124
    AND listings.lng BETWEEN 40.123 AND 40.124
    AND some_timestamp BETWEEN DATE_SUB( NOW(), INTERVAL 0 DAY) AND DATE_SUB( NOW(), INTERVAL 5 DAY)')
    JOIN (SELECT price, lat, lng, MAX(some_timestamp) as latest FROM listings GROUP BY price, lat, lng) as t2', 'listings.price=t2.price AND listings.lat=t2.lat AND listings.lng=t2.lng AND listings.some_timestamp=t2.latest', 'inner')
    LIMIT 200,0

列:

(索引列以粗体显示)

(以 property_ 开头的列是可选过滤器,前 2 个除外)

  • listing_id int(8)
  • url varchar(255)
  • city varchar(32)
  • somename varchar(32)
  • 价格 int(7)
  • price_per int(7)
  • property_1 int(2)
  • property_2 int(2)
  • address_1 varchar(255)
  • address_2 carchar(255)
  • city varchar(64)
  • 状态 varchar(32)
  • 邮政整数(6)
  • some_timestamp 时间戳
  • another_timestamp 时间戳
  • 纬度浮点数(10)
  • lng 浮点数(10)
  • 说明文字
  • img_subpath varchar(15)
  • 照片文字
  • reply_email varchar(255)
  • 电话 varchar(16)
  • property_3 tinyint(1)
  • property_4 tinyint(1)
  • property_5 tinyint(1)
  • property_6 tinyint(1)
  • property_7 tinyint(1)
  • property_8 tinyint(1)
  • property_9 tinyint(1)
  • property_10 tinyint(1)
  • property_11 tinyint(1)
  • property_12 tinyint(1)
  • property_13 tinyint(1)
  • property_14 tinyint(1)

问题:数据库获取结果的时间过长(3-4 秒)。如何在非常相似的网站上将其加速到

如果我有 2 个表,第一个表将只包含搜索中涉及的列,而下一个表包含所有其他列。所以当搜索发生时,它会搜索第一个表,获取结果的listing_id,然后使用IN 子句从第二个表中检索所有其他数据?

请指教,谢谢!

【问题讨论】:

  • 您的查询在自连接/子选择中出现了一些语法错误,因为您已将其粘贴在上面。
  • 我正在使用 Codeigniter 的活动记录语法并尝试转换为完整的 MySQL 查询。不太清楚实际的 SQL 代码如何

标签: mysql database database-design activerecord relational-database


【解决方案1】:

我认为您正在尝试通过以下方式获取过去五天的时间戳:

AND some_timestamp BETWEEN DATE_SUB( NOW(), INTERVAL 0 DAY)
AND DATE_SUB( NOW(), INTERVAL 5 DAY)')

如果是这样的话,应该是一样的

AND some_timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 5 DAY)) AND NOW()

如果您没有带有 some_timestamp 且具有未来值的记录,您可以使用

AND some_timestamp > DATE_SUB(NOW(), INTERVAL 5 DAY))

现在,我认为这应该会更快

SELECT listing_id, listings.property_1, property_2, address_1, address_2, city,
    listings.lat, listings.lng, img_subpath, photos, some_timestamp
FROM t2
LEFT JOIN listings
    ON (listings.price=t2.price AND listings.lat=t2.lat AND listings.lng=t2.lng
        AND t2.some_timestamp < listings.some_timestamp)
WHERE listings.lat BETWEEN 61.123 AND 61.124
    AND listings.lng BETWEEN 40.123 AND 40.124
    AND some_timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 5 DAY)) AND NOW()
    AND t2.some_timestamp is null
LIMIT 200

PS:我不认为拆分表会大大提高性能...实际上,如果您必须将两个表都连接起来才能得到结果,那就需要更多

【讨论】:

    【解决方案2】:

    您所提出的在某种程度上是索引如何工作的理论。减速很可能来自加入聚合子选择。我建议预先汇总该信息(无法立即看到任何您不能看到的原因)并加入该表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 1970-01-01
      • 2013-01-21
      • 1970-01-01
      • 2012-09-14
      • 2013-08-27
      • 2017-11-15
      相关资源
      最近更新 更多