Quy tắc chung cho bất kỳ ứng dụng nào là để cho DB làm tốt những việc mà nó làm:lọc, sắp xếp và kết hợp.
Tách các truy vấn thành các hàm hoặc phương thức lớp của riêng chúng:
$men = $foo->fetchMaleUsers();
$women = $foo->fetchFemaleUsers();
Cập nhật
Tôi đã trình diễn PostgreSQL của Steven về một truy vấn quét toàn bảng hoạt động tốt gấp đôi so với hai truy vấn được lập chỉ mục riêng biệt và bắt chước nó bằng MySQL (được sử dụng trong câu hỏi thực tế):
Lược đồ
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
Tôi đã thay đổi loại giới tính không phải là VARCHAR (20) vì nó thực tế hơn cho mục đích của cột này, tôi cũng cung cấp khóa chính như bạn mong đợi trên bảng thay vì giá trị DOUBLE tùy ý.
Kết quả không được lập chỉ mục
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)
Tôi tin rằng điều này không cần giải thích.
Kết quả được lập chỉ mục
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)
Kết quả được hiển thị ở đây là hoàn toàn khác với dữ liệu của Steven. Các truy vấn được lập chỉ mục hoạt động gần như nhanh gấp đôi so với quét toàn bộ bảng. Đây là từ một bảng được lập chỉ mục đúng cách sử dụng các định nghĩa cột thông thường. Tôi hoàn toàn không biết PostgreSQL, nhưng phải có một số cấu hình sai đáng kể trong ví dụ của Steven để không hiển thị kết quả tương tự.
Với danh tiếng của PostgreSQL về việc làm mọi thứ tốt hơn MySQL, hoặc ít nhất là tốt như vậy, tôi dám chắc rằng PostgreSql sẽ chứng minh hiệu suất tương tự nếu được sử dụng đúng cách.
Cũng xin lưu ý, trên cùng một máy này, vòng lặp for được đơn giản hóa quá mức để thực hiện 52 triệu phép so sánh mất thêm 7,3 giây để thực thi.
<?php
$N = 52000000;
for($i = 0; $i < $N; $i++) {
if (true == true) {
}
}
Tôi nghĩ rõ ràng đâu là cách tiếp cận tốt hơn với dữ liệu này.