Xin phép mod tí, subject này đáng nhẽ phải ở bên hệ csdl, nhưng e đã đăng bài bên đấy nhưng ko có ai respond cả, vấn đề của e lại đang rất cấp thiết, thấy bên này giải quyết vấn đề csdl rất nhiều nên nhờ mod tí nhé.
e đang làm code lấy dữ liệu từ rss các báo. (ví dụ:http://vnexpress.net/rss/gl/xa-hoi.rss)
khi insert tin vào csdl , em so sánh title (ví dụ: "Quý bà đâm ôtô vào trường mầm non, một người chết") đã có trong cơ sở dữ liệu chưa em dùng như sau:
(bảng chứa tin gồm 4 cột id, title , description, date)
$sql_check="SELECT id FROM `news` WHERE title='$title' and date >= DATE_SUB(CURDATE(), INTERVAL 100 DAY)";
$query_check=mysql_query($sql_check);
//nếu $query rỗng ~ tin chưa có trong csdl thì insert
if(@mysql_num_rows($query_check) == "" ) {
$sql= "insert into news (title,description,date) values ('$title','$description',now)";
mysql_query($sql);
}
code chạy gần một tuần thì rất tốt. Nhưng khi dữ liệu đã nhiều. Khi row đã lên tới 100.000 thì việc so sánh này khá là nặng, đặc biệt biệt là khi câu lệnh so sánh và insert này được đặt trong vòng lặp while, vì lúc bóc dữ liệu từ một list các rss khác nhau, mỗi title sẽ được so sánh một lần.(mỗi lần lướt qua cái list rss nó phải so sánh cỡ khoảng 15.000 cái title,nghĩa là 1 lần chạy file sẽ check 15.000 title vs 100.000 row hiện có trong bảng, số một 100.000 này sẽ tăng theo thời gian).
Trong thời gian chạy thử, em đã làm host sập 3 lần. Thấy chủ nó kêu ghê quá nên chuyển host. Chuyển sang host mới đc hơn một tuần host mới die luôn.
Qua tìm hiểu em cũng tìm thấy một số cách tối ưu hóa sau đây, cả nhà chỉ cho em cách nào là optimize nhất nhé:
vấn đề 1. Tạo thêm cột title_md5 để chứa title mã hóa dưới dạng md5, khi so sánh có lẽ sẽ nhẹ hơn.
2. cột lưu trữ mã hóa md5 thì nên để kiểu dữ liệu gì varchar(?bao nhiêu ký tự), hay text....?
3. Set full text search, unique index cho cột title_md5 để truy vấn cho nhanh (vấn đề là khi truy vấn dữ liệu dạng này thi nên set unique index hay full text search hay cả hai).
4. có phải nếu dùng unique index thì nó sẽ ko cho insert title,description khi mà md5_title đã tồn tại trong csdl, nếu đc như vậy thì quá tốt vì đỡ phải so sánh mất thêm một query so sánh đúng ko ạ ?
5. mỗi lần insert dữ liệu vào bảng có phải thêm lệnh create index lại cho bảng ko hay chỉ cần create index một lần, về sau khi insert bảng sẽ tự đánh chỉ mục lại ?
6. cái này có đúng ko:việc dùng chức năng fulltextsearch ngốn nhiều tài nguyên máy ( khoảng 100K dòng là dể bị overload server lắm).vậy trường hợp này nên dùng creat unique index và bỏ full text search? E đã tìm đọc rất nhiều nhưng ko thể tìm đc kết quả trường hợp này dùng create index và full text search cái nào sẽ nhanh hơn ?
Mọi người lưu ý sẽ là data vài triệu dòng nhé. Vài phút cronjob sẽ chạy một lần nên tính ra truy vấn so sánh sẽ nhiều hơn rất nhiều so với insert: truy vấn so sánh từ 14000 đến 15000 một lần chạy cron, còn insert chỉ vài trăm vì mình chạy rà soát các rss liên tục.
7. sử dụng câu kiểm tra như thế này có nhanh hơn là câu lệnh bên trên:
IF EXISTS (SELECT id FROM table_name WHERE title = '***')
8. Với câu này kiểm tra này thì sao:
SELECT count(*) FROM table_name WHERE MATCH (fi) AGAINST ('value');
9. Trường hợp này có nên sử dụng mysql_pconnect() thay cho mysql_connect().
10. Có ai biết cách đo thời gian thực thi một câu lệnh query thì cho e xin mấy dòng code đấy nhé.
PS: Ngoài ra thấy mọi người thấy còn cách nào hay hơn thì cho e xin gợi ý. Thanks cả nhà!
Bookmarks