我试图为我的表创建一些统计数据,但它有超过300万行,所以它真的很慢。
我正在尝试为列name
找到最受欢迎的值,并显示它弹出的次数。
我在妈妈那里使用它但它不起作用因为它太慢而且我只是得到错误。
$total = mysql_query("SELECT `name`, COUNT(*) as b FROM `people` GROUP BY `name` ORDER BY `b` DESC LIMIT 0,5;")or die(mysql_error());
正如您所看到的,我正在尝试获取所有名称以及该名称的使用次数,但只显示前5名,以便加快速度。
我希望能够获得像
这样的值 while($row = mysql_fetch_array($result)){
echo $row['name'].': '.$row['b']."\r\n";
}
它会显示这样的事情;
Bob: 215
Steve: 120
Sophie: 118
RandomGuy: 50
RandomGirl: 50
我对后来的名字排序并不在意,比如RandomGirl和RandomGuy是错误的方式。
我想我已经提供了足够的信息。 :)我希望这些名称尽可能不区分大小写。 Bob应该与BoB,bOb,BOB等相同。
谢谢你的时间 保罗
答案 0 :(得分:5)
限制前5名的结果不会给你带来很多加速,你会在结果检索中获得时间,但在mySQL方面,整个表仍然需要被解析(计算)。
你将加速你的计数查询在名称列上有索引,当然因为只会解析索引而不是表。
现在,如果你真的想要加速结果并避免在你需要这个结果时解析名称索引(如果你真的有数百万行,这仍然会很慢),那么唯一的另一个解决方案是计算统计数据时在此表上插入,删除或更新行。这是在此表上使用触发器来维护靠近此表的统计信息表。那么你真的只在这个统计表上有一个简单的选择查询,只解析了5行。但是你会减慢插入,删除和更新操作的速度(这已经非常慢了,特别是如果你维护索引,所以如果统计数据很重要,你应该研究这个解决方案。)
答案 1 :(得分:2)
你有名字索引吗?这可能有所帮助。
答案 2 :(得分:1)
由于您正在进行计数/分组,然后对名称上的索引进行排序并没有帮助MySql每次都应该遍历所有行,因此无法对其进行优化。你需要有一个单独的 stats 表,如下所示:
CREATE TABLE name_stats( name VARCHAR(n), cnt INT, UNIQUE( name ), INDEX( cnt ) )
每当你向'people'表添加一个新行时,你应该更新这个表:
INSERT INTO name_stats VALUES( 'Bob', 1 ) ON DUPLICATE KEY UPDATE cnt = cnt + 1;
查询此表以获取顶级名称列表,可以立即为您提供结果。