Php 如何优化我的查询?
我有3个表Php 如何优化我的查询?,php,mysql,sql,Php,Mysql,Sql,我有3个表country\u data、user\u data和topic\u data,表结构如下所示 国家数据: name | code ---------------|--------------- India | IN United States | US Australia | AU user_ip | topic_code | country ---------------|---------------|---
country\u data、user\u data
和topic\u data
,表结构如下所示
国家数据:
name | code
---------------|---------------
India | IN
United States | US
Australia | AU
user_ip | topic_code | country
---------------|---------------|---------------
192.168.1.1 | topic_code_1 | India
192.168.1.2 | topic_code_2 | United States
192.168.1.3 | topic_code_3 | Australia
name | code
---------------|---------------
topic_1 | topic_code_1
topic_2 | topic_code_2
topic_3 | topic_code_3
用户数据:
name | code
---------------|---------------
India | IN
United States | US
Australia | AU
user_ip | topic_code | country
---------------|---------------|---------------
192.168.1.1 | topic_code_1 | India
192.168.1.2 | topic_code_2 | United States
192.168.1.3 | topic_code_3 | Australia
name | code
---------------|---------------
topic_1 | topic_code_1
topic_2 | topic_code_2
topic_3 | topic_code_3
主题\u数据:
name | code
---------------|---------------
India | IN
United States | US
Australia | AU
user_ip | topic_code | country
---------------|---------------|---------------
192.168.1.1 | topic_code_1 | India
192.168.1.2 | topic_code_2 | United States
192.168.1.3 | topic_code_3 | Australia
name | code
---------------|---------------
topic_1 | topic_code_1
topic_2 | topic_code_2
topic_3 | topic_code_3
我在user\u数据表中有大约十万(100000)行
我想要的是,我需要过滤来自每个国家的用户数量,以及针对给定主题的相应国家代码。例如,我需要每个国家查看主题2
的用户数。重新查询的输出格式为
country_code | count
---------------|---------------
IN | 150
US | 120
AU | 100
现在请检查我的查询:
SELECT cd.code, COUNT(ud.country) as count
FROM topic_data as td, user_data as ud, country_data as cd
WHERE td.name = 'topic_1' AND td.code = ud.topic_code AND ud.country = cd.name
GROUP BY ud.country
在phpmyadmin中完成此操作大约需要2秒钟。在php网页中,即使在服务器中加载页面也需要15秒。通过删除查询中的group by,即group by ud.country
,执行所需时间超过30秒,输出的是最后一个国家代码和所有国家/地区的访问总数。我做错了什么?请帮忙
----更新---
使用外键修改了表,我的查询也是如此。现在它以闪电般的速度工作。感谢那些帮助过你的人。在我看来,这个查询看起来不太糟糕。但是数据的标准化看起来有点奇怪,例如,为什么在user\u data
表上有一个country
(name)字段,只是为了加入name上的country
来查找代码?相反,对我来说更符合逻辑的事情是逐个国家引用代码(或其他索引键约束)。如果您只需要示例查询中的代码,这还将保存一个到国家/地区的加入。如果user\u data
是一个高容量表,则需要将其中的数据保持在最小值,以减少读取(密度)时的IO
此外,顺便说一句,使用JOIN
而不是WHERE
子句进行连接将提高代码的可读性,IMO:
SELECT cd.code, COUNT(ud.country) as count
FROM topic_data as td
INNER JOIN user_data as ud
ON td.code = ud.topic_code
INNER JOIN country_data as cd
ON ud.country = cd.name
WHERE td.name = 'topic_1'
GROUP BY ud.country;
要解决性能问题,请检查以下索引是否到位:
- 主题数据的索引。名称
- 外键上的索引
user\u data.topic\u code
和user\u data.country
(或user\u data.country\u code
,如果将外键更改为user\u data.country\u code
)
试试这个:
使用以下数据库结构在内部JOIN语句中使用数字匹配可能会减少搜索时间,
因此,为表的id列编制索引(例如主键):
并运行多个内部连接状态,如:
SELECT cd.code, count(ud.topic_code) as count
FROM ud
INNER JOIN cd ON cd.id = ud.country
INNER JOIN td ON td.id = ud.topic_code
WHERE td.code='topic_1'
GROUP BY ud.country;
主键优化?为什么存储country的全文而不是country表中可用的唯一键?这些表有哪些索引?您能否提供查询的解释计划?请添加数据库表的定义查询。我们需要查看您的索引、主键、外键和表引擎。@Jon user_数据表是旧的,country_数据表是我为此添加的。我不能换桌子。这样做,会影响到这么多的页面。这是你的问题。您需要正确设置表,如果您觉得不能,那么您的应用程序是以脚本无法升级的方式创建的。为了减少查询,您确实需要分配和可用的外键。我希望在第二次尝试此查询后,您错过了一次打开。在localhost中第一次执行后,它工作正常。但在服务器上仍然存在问题。后续执行只会缩短时间。第一次查询在phpmyadmin中花费了0.9851秒。让我尝试优化这些值。thanx。。。。