すべてのアプリケーションの経験則は、DBに、フィルタリング、並べ替え、結合などの優れた機能を実行させることです。
クエリを独自の関数またはクラスメソッドに分割します:
$men = $foo->fetchMaleUsers();
$women = $foo->fetchFemaleUsers();
更新
私は、2つの別々のインデックス付きクエリの2倍のパフォーマンスを発揮する全表スキャンクエリの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)
ここに表示される結果は根本的にです スティーブンのデータとは異なります。インデックス付きクエリはほぼ実行されます 全表スキャンの2倍の速度。これは、常識的な列定義を使用して適切にインデックス付けされたテーブルからのものです。 PostgreSQLについてはまったく知りませんが、同様の結果を表示しないようにするには、Stevenの例にいくつかの重大な設定ミスがあるはずです。
MySQLよりも優れている、または少なくとも同じくらい優れているというPostgreSQLの評判を考えると、PostgreSqlを適切に使用すれば、同様のパフォーマンスを発揮することをあえて言います。
また、この同じマシンでは、5,200万回の比較を行うforループが過度に単純化されているため、さらに7.3秒かかることに注意してください。 実行します。
<?php
$N = 52000000;
for($i = 0; $i < $N; $i++) {
if (true == true) {
}
}
このデータを考えると、より良いアプローチが何であるかはかなり明白だと思います。