Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 你能告诉我这个问题出了什么问题吗?_Mysql - Fatal编程技术网

Mysql 你能告诉我这个问题出了什么问题吗?

Mysql 你能告诉我这个问题出了什么问题吗?,mysql,Mysql,大家好 我使用的是单个数据库和大约7个表。所有表格都要填写数据。 现在大约有10公里。但会进一步增长,可能会影响数百万人,但这需要时间 我的问题是为什么我的查询获取结果很慢。查询非负载条件大约需要10到12秒。我担心的是,如果在负载条件下发生的情况是一次有数千个查询 这是我的示例查询 $result = $db->sql_query("SELECT * FROM table1,table2,table3,table4,table5 WHERE table1.url = table2.url

大家好

我使用的是单个数据库和大约7个表。所有表格都要填写数据。 现在大约有10公里。但会进一步增长,可能会影响数百万人,但这需要时间

我的问题是为什么我的查询获取结果很慢。查询非负载条件大约需要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}

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


您可能会发现在分析查询时有所帮助。

每个表的url字段上都有一个索引,这是查找联接的方法,尤其是查看内部联接、左侧联接和外部联接之间的差异。还要为要进行查找的所有字段编制索引。

索引可能有问题

在任何情况下,像URL这样的长字符串都会导致主键性能不佳。索引占用了索引中大量的空间,因此索引并不像它们可能的那样密集,并且每个IO加载的行指针更少。同样对于URL,99%的字符串都是以开头的。因此,数据库引擎必须比较13个字符,然后才能确定一行不匹配

一种解决方案是使用一些散列函数,如MD5、SHA1甚至CRC32,从字符串中获取原始二进制值,并将该值用作表的主键。CRC32是一个不错的整数大小的主键,但几乎可以肯定的是,在某个阶段,您将遇到两个url,它们散列到相同的CRC32值,因此您需要存储并比较url字符串以确保。其他散列函数在原始模式下分别返回16字节和20字节的较长值,但冲突的可能性非常小,不值得担心


.

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

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

以下脚本创建一个存储过程,用于用10000行数据填充每个表:

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();
这几乎会立即产生以下结果:

+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+
| 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 * 
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_类型很简单,这意味着没有JOIN语句来降低速度

类型为const,这意味着该表最多有一个可能的匹配项-这要归功于唯一索引,它保证了没有两个URL是相同的。有关唯一索引的详细描述,请参阅。type列中的const值与您可以得到的值差不多

可能的_键和键使用url键。这意味着每个表都使用了正确的索引

ref是const,这意味着MySQL正在比较一个常量值,该常量值不会随索引而改变。同样,这是非常快的

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

额外的是使用索引。MySQL不必对表进行任何额外的非索引搜索


如果在每个表的url列上都有索引,则查询速度应该非常快。

url字段是否已索引?什么是tfdata.web?@Lasse V.Karlsen…很抱歉,这是一个错误,我更正了itOk,但是在更正之后,您的url字段是否已被索引?是的,唯一索引…通过检查??您是否已从控制台(即PHP外部)测试SQL命令,以确定它是否与SELECT本身有关,或者问题出在别处?另外,发布showcreatetablete1的结果我假设所有的表都有相同的结构,如果没有,也可以发布其他的表结构。最后,您应该提供EXPLAIN SELECT语句的输出。我已经为列“url”上的所有表编制了索引,并且查询了EXPLAIN,它返回了整个表结构……但我需要从中了解的是??哦,我为url列添加了唯一索引。因为我不想要任何重复…这会造成任何干扰吗?唯一索引是一个索引。至于理解和解释,,检查一下,表4似乎有索引问题,它没有主键。我不知道它创建时发生了什么。有人能告诉我如何将数据从表4复制到表4-1吗?哦,对不起,一切都很好。似乎我将发布result@mathew剥掉www是一个错误。例如,
www.somedomain.com与somedomain.com不同。是的,现在大多数网站的DNS条目都指向同一个web服务器,但这只是一种惯例。无论如何,从一个URL中去掉3个字符不会使大多数URL缩短很多;MySQL说:文档1064-您的SQL语法有错误;检查与MySQL服务器版本对应的手册,在第3行附近使用正确的语法。他们完成了…我得到了您显示的确切结果…这意味着一切正常吗??那么我需要改变我桌子的整体结构……但是如果它很快,那么我就很快happy@mathew:错误1064指的是使用。您使用的是什么版本的MySQL?您是否复制并粘贴了函数,并完成了分隔符语句?非常感谢您让我进行此测试,并使用少量SQL知识更新我。我目前正在使用MyISAM,所以我是否创建一个新表并填充它??如果是这样,我该怎么做?我将创建新表,但如何用另一个表上的数据填充它
+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+------+-----------------------------+
| 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 * 
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 |
+----+-------------+--------+-------+---------------+------+---------+-------+------+-------------+