0

我对一个大的 mysql 查询(mysql 5.0)感到头疼,我希望这里有人能提供帮助。

之前我问过如何从连接查询中获取不同的值 mysql count only for distinct values in join query

我得到的响应(使用带有连接的子查询)

选择 *
来自媒体 m
内部联接
     (选择uid
     来自 users_tbl
     限制 0,30) 地图
  在 map.uid = m.uid
内连接 users_tbl u
  在 u.uid = m.uid

不幸的是,我的查询变得越来越不守规矩,虽然我运行它,但加入派生表需要太长时间,因为派生查询没有可用的索引。

我的查询现在看起来像这样

选择 mdate.bid, mdate.fid, mdate.date, mdate.time, mdate.title, mdate.name,
       mdate.address, mdate.rank, mdate.city, mdate.state, mdate.lat, mdate.`long`,
       分机链接,
       ext.source、ext.pre、meta、mdate.img
从分机
右外连接(
  选择 media.bid,
         media.date, media.time, media.title, users.name, users.img, users.rank, media.address,
         media.city, media.state, media.lat, media.`long`,
         GROUP_CONCAT(tags.tagname SEPARATOR ' | ') 作为元
  来自媒体
  在 media.bid = users.bid 上加入用户
  LEFT JOIN tags ON users.bid=tags.bid
  在 -122.52224684058 和 -121.79760915942 之间的“长”
    和 37.07500915942 和 37.79964684058 之间的纬度
    AND 日期 = '2009-02-23'
  GROUP BY media.bid, media.date
  ORDER BY media.date, users.rank DESC
  限制 0, 30
) mdate ON (mdate.bid = ext.bid AND mdate.date = ext.date)

呸!

所以,正如你所看到的,如果我正确理解了我的问题,我有两个没有索引的派生表(我不否认我可能以某种方式搞砸了 Join 语句,但我一直在搞乱不同的类型,这结束了吗给我我想要的结果)。

创建与此类似的查询的最佳方法是什么,这将使我能够利用索引?我敢说,我实际上还有一张桌子可以在以后添加到组合中。

目前,我的查询需要 0.8 秒才能完成,但我确信如果我可以利用索引,这可能会快得多。

4

3 回答 3

1

新鲜开始:

问题 - 为什么要同时按 media.bid 和 media.date 分组?投标可以有多个日期的记录吗?

这是一个更简单的尝试版本:

SELECT 
    mdate.bid,
    mdate.fid,
    mdate.date,
    mdate.time,
    mdate.title,
    mdate.name, 
    mdate.address,
    mdate.rank,
    mdate.city,
    mdate.state,
    mdate.lat,
    mdate.`long`,
    ext.link, 
    ext.source,
    ext.pre, 
    meta,
    mdate.img,
    (   SELECT GROUP_CONCAT(tags.tagname SEPARATOR ' | ')
        FROM tags 
        WHERE ext.bid = tags.bid
        ORDER BY tags.bid GROUP BY tags.bid
    ) AS meta

FROM 
    ext

LEFT JOIN
    media ON ext.bid = media.bid AND ext.date = media.date

JOIN
    users ON ext.bid = users.bid

WHERE 
    `long` BETWEEN -122.52224684058 AND -121.79760915942
    AND lat BETWEEN 37.07500915942 AND 37.79964684058
    AND ext.date = '2009-02-23'
    AND users.userid IN
    (    
        SELECT userid FROM users ORDER BY rank DESC LIMIT 30
    )

ORDER BY 
    media.date, 
    users.rank DESC
    LIMIT 0, 30
于 2009-02-23T19:52:01.693 回答
1

首先,检查ext(bid, date),users(bid)和上的索引tags(bid),你真的应该拥有它们。

但是,它似乎是LONG并且LAT会导致您遇到大多数问题。您应该尝试将LONGand保留LAT为,在此列上创建 a并像这样查询:(coordinate POINT)SPATIAL INDEX

WHERE MBRContains(@MySquare, coordinate)

如果由于某种原因无法更改架构,您可以尝试创建包含date作为第一个字段的附加索引:

CREATE INDEX ix_date_long ON media (date, `long`)
CREATE INDEX ix_date_lat ON media (date, lat)

这些索引对您的查询会更有效,因为您使用精确搜索 ondate结合范围搜索 on axes

于 2009-02-23T20:08:54.557 回答
0

您可能希望将您的性能与为每个选择使用临时表进行比较,并将这些表连接在一起。

创建表#whatever 创建表#whatever2

插入 #whatever 选择... 插入 #whatever2 选择...

选择 #whatever 加入 #whatever 2

……

删除表 #whatever 删除表 #whatever2

如果您的系统有足够的内存来保存完整的表,这可能会更快。这取决于你的数据库有多大。

于 2009-02-24T05:45:32.797 回答