大家好
我使用的是一个数据库和大约7个表。确保所有表都填充了数据%s。到目前为止,大约有10k。但会进一步增长,可能会冲击数百万人,但需要时间。
我的问题是为什么我的查询获取结果的速度很慢。对于非加载条件的查询,大约需要10到12秒。我担心在负载条件下会发生什么,比如说一次有数千个查询??
下面是我的示例查询...
$result = $db->sql_query("SELECT * FROM table1,table2,table3,table4,table5 WHERE table1.url = table2.url AND table1.url = table3.url AND table1.url = table4.url AND table1.url = table5.url  AND table1.url='".$uri."'")or die(mysql_error());
$row = $db->sql_fetchrow($result);
$daysA = $row['regtime'];
$days = (strtotime(date("Y-m-d")) - strtotime($row['regtime'])) / (60 * 60 * 24);
if($row > 0 && $days < 2){
$row['data'];
$row['data1'];
//remaining 
}else{ //some code}发布于 2010-06-29 16:40:07
我不确定你是否已经解决了这个问题,但这是我制作的一些测试数据。有许多因素会影响您的查询速度,因此我的简单测试用例可能无法准确地反映您的表或数据。然而,它们可以作为一个有用的起点。
首先,创建5个简单的表,每个表都具有相同的结构。与您的表一样,我在url列上使用了UNIQUE索引:
CREATE TABLE `table1` (
    `id` int(11) NOT NULL auto_increment,
    `url` varchar(255) default NULL,
    PRIMARY KEY  (`id`),
    UNIQUE KEY `url` (`url`)
) ENGINE=InnoDB;
CREATE TABLE table2 LIKE table1;
CREATE TABLE table3 LIKE table1;
CREATE TABLE table4 LIKE table1;
CREATE TABLE table5 LIKE table1;以下脚本创建一个存储过程,用于在每个表中填充10,000行数据:
DELIMITER //
DROP PROCEDURE IF EXISTS test.autofill//
CREATE PROCEDURE test.autofill()
BEGIN
    DECLARE i INT DEFAULT 5;
    WHILE i < 10000 DO
        INSERT INTO table1 (url) VALUES (CONCAT('wwww.stackoverflow.com/', i ));
        INSERT INTO table2 (url) VALUES (CONCAT('wwww.stackoverflow.com/', 10000 - i ));
        INSERT INTO table3 (url) VALUES (CONCAT('wwww.stackoverflow.com/', i + 6000 ));
        INSERT INTO table4 (url) VALUES (CONCAT('wwww.stackoverflow.com/', i + 3000 ));
        INSERT INTO table5 (url) VALUES (CONCAT('wwww.stackoverflow.com/', i + 2000 ));
        SET i = i + 1;
    END WHILE;
END;
//
DELIMITER ;
CALL test.autofill();现在,每个表包含10,000行。现在可以使用您的SELECT语句来查询数据:
SELECT * 
FROM table1,table2,table3,table4,table5
WHERE table1.url = table2.url
AND table1.url = table3.url
AND table1.url = table4.url
AND table1.url = table5.url
AND table1.url = 'wwww.stackoverflow.com/8000';这几乎可以立即产生以下结果:
+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+
| id   | url                         | id   | url                         | id   | url                         | id   | url                         | id   | url                         |
+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+
| 7996 | wwww.stackoverflow.com/8000 | 1996 | wwww.stackoverflow.com/8000 | 1996 | wwww.stackoverflow.com/8000 | 4996 | wwww.stackoverflow.com/8000 | 5996 | wwww.stackoverflow.com/8000 |
+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+EXPLAIN SELECT显示了查询速度非常快的原因:
EXPLAIN SELECT * 
FROM table1,table2,table3,table4,table5
WHERE table1.url = table2.url
AND table1.url = table3.url
AND table1.url = table4.url
AND table1.url = table5.url
AND table1.url = 'wwww.stackoverflow.com/8000';
+----+-------------+--------+-------+---------------+------+---------+-------+------+-------------+
| id | select_type | table  | type  | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+--------+-------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | table1 | const | url           | url  | 258     | const |    1 | Using index |
|  1 | SIMPLE      | table2 | const | url           | url  | 258     | const |    1 | Using index |
|  1 | SIMPLE      | table3 | const | url           | url  | 258     | const |    1 | Using index |
|  1 | SIMPLE      | table4 | const | url           | url  | 258     | const |    1 | Using index |
|  1 | SIMPLE      | table5 | const | url           | url  | 258     | const |    1 | Using index |
+----+-------------+--------+-------+---------------+------+---------+-------+------+-------------+select_type是SIMPLE,这意味着没有JOIN语句来减慢速度。
type是const,这意味着表最多有一个可能的匹配项-这要归功于UNIQUE索引,它保证不会有两个URL是相同的(有关UNIQUE INDEX的详细描述,请参阅mysql 5.0 indexes - Unique vs Non Unique )。type列中的const值就是您能得到的最好的值了。
possible_keys和key使用url密钥。这意味着每个表都使用了正确的索引。
ref为const,这意味着MySQL将一个常量值(不变的值)与索引进行比较。同样,这是非常快的。
rows等于1。MySQL只需要查看每个表中的一行。再一次,这是非常快的。
Extra是Using index。MySQL不必对表执行任何额外的非索引搜索。
假设您在每个表的url列上都有一个索引,那么您的查询应该会非常快。
发布于 2010-06-29 15:11:46
听起来WHERE子句中的一些列可能不是indexed。索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后遍历整个表以查找相关行。
您可能会发现EXPLAIN在分析查询方面很有帮助。
发布于 2010-06-29 15:15:31
在每个表中的url字段上看起来绝对像索引是可行的
https://stackoverflow.com/questions/3138559
复制相似问题