好的,这是一个简单的问题抽象:
2个变量(male_users和female_users)用于存储2组用户,即男性和女性
select * from users where gender = 'male'
然后将结果存储在male_users
select * from users where gender = 'female
'然后将结果存储在female_users
'select * from users
'然后循环结果集以过滤程序中的男性用户
php代码片段会像这样:
$result = mysql_query('select * from users');
while (($row=mysql_fetch_assoc(result)) != null) {
if ($row['gender'] == 'male'){// add to male_users}
else if ($row['gender'] == 'female'){// add to female_users}
}
哪一个更有效并被认为是更好的方法?
这只是问题的简单说明。真实的项目可能有更大的表格来查询和更多的过滤选项。
提前感谢!
答案 0 :(得分:9)
任何应用程序的经验法则都是让数据库执行它做得很好的事情:过滤,排序和加入。
将查询分成他们自己的函数或类方法:
$men = $foo->fetchMaleUsers();
$women = $foo->fetchFemaleUsers();
我使用Steven的PostgreSQL演示了一个全表扫描查询,执行两次单独的索引查询,并使用MySQL模拟它(在实际问题中使用):
CREATE TABLE `gender_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`gender` enum('male','female') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26017396 DEFAULT CHARSET=utf8
我将性别类型更改为不是VARCHAR(20),因为它对于此列的目的更为现实,我还提供了一个主键,就像您期望在表上而不是任意的DOUBLE值。
mysql> select sql_no_cache * from gender_test WHERE gender = 'male';
12995993 rows in set (31.72 sec)
mysql> select sql_no_cache * from gender_test WHERE gender = 'female';
13004007 rows in set (31.52 sec)
mysql> select sql_no_cache * from gender_test;
26000000 rows in set (32.95 sec)
我相信这不需要解释。
ALTER TABLE gender_test ADD INDEX (gender);
...
mysql> select sql_no_cache * from gender_test WHERE gender = 'male';
12995993 rows in set (15.97 sec)
mysql> select sql_no_cache * from gender_test WHERE gender = 'female';
13004007 rows in set (15.65 sec)
mysql> select sql_no_cache * from gender_test;
26000000 rows in set (27.80 sec)
此处显示的结果从根本上与Steven的数据不同。索引查询执行几乎的速度是全表扫描的两倍。这是使用常识列定义的正确索引表。我根本不了解PostgreSQL,但是在Steven的例子中必须有一些重要的错误配置才能显示出类似的结果。
鉴于PostgreSQL比MySQL做得更好的声誉,或者至少和MySQL一样好,我敢说如果使用得当,PostgreSql会表现出类似的性能。
另请注意,在同一台机器上,执行5200万次比较的过度简化的for循环需要额外的7.3秒才能执行。
<?php
$N = 52000000;
for($i = 0; $i < $N; $i++) {
if (true == true) {
}
}
我认为给出这些数据的更好方法是显而易见的。
答案 1 :(得分:4)
答案 2 :(得分:0)
如果您有100万用户,您更喜欢(考虑其中一半是男性,一半是女性):
我想你会回答说你更喜欢只取一半的用户;-)并且,根据条件,如果更复杂,它甚至可能比这还要小。
基本上,获取更少的数据意味着:
在一般情况下,我们会尽量避免获取更多必要的数据;即我们将过滤放在数据库端。
当然,这意味着您必须考虑将要放在数据库表中的索引:它们必须满足您将要执行的查询的需要。