首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >你能说出这个查询出了什么问题吗?

你能说出这个查询出了什么问题吗?
EN

Stack Overflow用户
提问于 2010-06-29 15:08:51
回答 5查看 334关注 0票数 0

大家好

我使用的是一个数据库和大约7个表。确保所有表都填充了数据%s。到目前为止,大约有10k。但会进一步增长,可能会冲击数百万人,但需要时间。

我的问题是为什么我的查询获取结果的速度很慢。对于非加载条件的查询,大约需要10到12秒。我担心在负载条件下会发生什么,比如说一次有数千个查询??

下面是我的示例查询...

代码语言:javascript
运行
复制
$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}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-06-29 16:40:07

我不确定你是否已经解决了这个问题,但这是我制作的一些测试数据。有许多因素会影响您的查询速度,因此我的简单测试用例可能无法准确地反映您的表或数据。然而,它们可以作为一个有用的起点。

首先,创建5个简单的表,每个表都具有相同的结构。与您的表一样,我在url列上使用了UNIQUE索引:

代码语言:javascript
运行
复制
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行数据:

代码语言:javascript
运行
复制
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语句来查询数据:

代码语言:javascript
运行
复制
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';

这几乎可以立即产生以下结果:

代码语言:javascript
运行
复制
+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+
| 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显示了查询速度非常快的原因:

代码语言:javascript
运行
复制
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_typeSIMPLE,这意味着没有JOIN语句来减慢速度。

typeconst,这意味着表最多有一个可能的匹配项-这要归功于UNIQUE索引,它保证不会有两个URL是相同的(有关UNIQUE INDEX的详细描述,请参阅mysql 5.0 indexes - Unique vs Non Unique )。type列中的const值就是您能得到的最好的值了。

possible_keyskey使用url密钥。这意味着每个表都使用了正确的索引。

refconst,这意味着MySQL将一个常量值(不变的值)与索引进行比较。同样,这是非常快的。

rows等于1。MySQL只需要查看每个表中的一行。再一次,这是非常快的。

ExtraUsing index。MySQL不必对表执行任何额外的非索引搜索。

假设您在每个表的url列上都有一个索引,那么您的查询应该会非常快。

票数 0
EN

Stack Overflow用户

发布于 2010-06-29 15:11:46

听起来WHERE子句中的一些列可能不是indexed。索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后遍历整个表以查找相关行。

您可能会发现EXPLAIN在分析查询方面很有帮助。

票数 0
EN

Stack Overflow用户

发布于 2010-06-29 15:15:31

在每个表中的url字段上看起来绝对像索引是可行的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3138559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档