如何格式化这个mysql查询

时间:2012-08-03 11:49:53

标签: mysql select where

我所拥有的是一张表格,包含ip,浏览器信息的哈希值,访问过的网址以及上次访问日期的时间戳。

我可以从不同的源代码编译导致此查询,唯一的问题是此查询需要在大约15000行的表上完成(9分钟),因此此查询效率非常低。

我想我会以错误的方式解决这个问题,但我找不到一个像样的帖子或教程如何使用select的结果作为获得我想要的结果的基础。

我只想要的是概述表中的每个条目,这些条目与返回的结果的哈希值相匹配,这些哈希值在过去12小时内访问了超过25页。

CREATE TABLE IF NOT EXISTS `statsitieken` (
  `hash` varchar(35) NOT NULL,
  `ip` varchar(24) NOT NULL,
  `visits` int(11) NOT NULL,
  `lastvisit` int(11) NOT NULL,
  `browserinfo` text NOT NULL,
  `urls` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

这是我到目前为止尝试编译的查询。

SELECT * FROM `database`.`statsitieken` WHERE hash in (SELECT hash FROM `database`.`statsitieken`
where `lastvisit` > unix_timestamp(DATE_SUB(
                                    NOW(),INTERVAL 12 hour
                                    )
                                )
group by hash
having count(urls) > 25
order by urls)

我需要在合适的时间内编译,比如<在我看来应该可以实现1秒......

3 个答案:

答案 0 :(得分:1)

我建议尝试这个修改过的查询。子查询现在只计算一次,而不是为每个返回的记录运行:

SELECT s.*
FROM `database`.`statsitieken` s, (SELECT *
FROM `database`.`statsitieken`
WHERE `lastvisit` > UNIX_TIMESTAMP(DATE_SUB(NOW(),INTERVAL 12 HOUR))
GROUP BY hash
HAVING COUNT(urls)>25) tmp
WHERE s.`hash`=tmp.`hash`
ORDER BY s.urls

请确保您在以下字段中包含索引:

  • hash加快GROUP BYWHERE
  • 的速度
  • urls加快ORDER BY

答案 1 :(得分:0)

INNER JOIN的派生表比子查询更快。尝试这个优化的查询:

SELECT *
FROM statsitieken a
    INNER JOIN (SELECT hash
                FROM statsitieken
                WHERE lastvisit > unix_timestamp(DATE_SUB(
                                    NOW(),INTERVAL 12 hour
                                    )
                ) b
        ON a.hash = b.hash
GROUP BY a.hash
HAVING COUNT(urls) > 25
ORDER BY urls;

为了更好地执行此选择查询,您应该将索引添加为:

ALTER TABLE statsitieken ADD KEY ix_hash(hash);

ALTER TABLE statsitieken ADD KEY ix_lastvisit(lastvisit);

答案 2 :(得分:0)

WHERE hash in (SELECT hash FROM `database`.`statsitieken`
where `lastvisit` > unix_timestamp(DATE_SUB(
                                    NOW(),INTERVAL 12 hour
                                    )
                            )

你是在同一张表中“subquerying”(我不知道是否存在这个词:P,'做一个子查询'),为什么不:

where `lastvisit` > unix_timestamp(DATE_SUB(
                                    NOW(),INTERVAL 12 hour
                                    )

直接做吗?