Home » TechNote » Speed up your website

Speed up your website

speed-up-website-image

Server side:

  • mySQL:
EXPLAIN SELECT statement

1. Bật chế độ slow_log trong mySQL theo cú pháp sau:

mysql> SET GLOBAL slow_query_log = ‘ON’;
Query OK, 0 rows affected (0.03 sec)

mysql> SET GLOBAL log_slow_queries = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> set global slow_query_log_file = ‘D:/wamp/slow_log.txt’;
Query OK, 0 rows affected (0.01 sec)



2. Từ  danh sách các câu SQL  trong file slow log, chúng ta có thể sủ dụng lệnh EXPLAIN  cho mỗi câu  SELECT để xem vấn đề, ví dụ “EXPLAIN SELECT ….”

Giải thích lệnh EXPLAIN:

– Select Types:
SIMPLE: Câu sql cơ bản, không có sub queries và union.
PRIMARY: Câu lệnh Select cấp độ cao nhất.
DERIVED: Câu queries có liên quan đến table gốc.
UNION: Câu lệnh queries là câu > 2 trong toàn bộ câu sql.

– Table : Table nào đang liên quan đến output data
– Type : Đây là thông tin quan trọng, nó cho chúng ta biết kiểu query nào đang sử dụng.
list up theo tốc độ query
* system:
* const: Câu sql dùng primary key hoặc unique key => very fast. (1)
* eq_ref: Câu sql dùng biểu trưng khóa ngoại kết nối khóa chính. (select cust.* from cust, comment where comment.id_cust * = cust.id) => fast (2)
* ref: Câu sql có dùng index bình thường (không unique) => medium (3)
* ref_or_null: Câu sql có dùng index bình thường (không unique) và tìm trong cả giá trị null trong index column => medium (4)
* index_merge: Câu sql có dùng nhiều index để tìm (do đặt index không đúng nên xảy ra tình trạng này). (4)
* unique_subqueries: Câu sql để lấy ra giá trị từ sub queries trả về primary (unique) key. Ví dụ câu select * from node * where id_cust in (select id from customers where fullname = ‘song’) sẽ trả về những record đều là primary (unique) key. (2)
* index_subqueries: Tương tự unique_subqueries nhưng lần này là lấy giá trị từ giá trị trả về là index key. VD: explain select * from node where id_cust in (select id_cust from comment where comment.name = ‘song’). (3)
* range: Trả về 1 vùng trong những row có dùng index, thường dùng cho những câu in, between… (4)
* index: Giống ALL nhưng nhanh hơn ALL 1 tí. (5)
* ALL: chậm nhất vì không dùng index. (6)
– possible_keys : Đưa ra những Index có thể sử dụng để query
– key : Index nào đang được sử dụng
– key_len : Chiều dài của từng mục trong Index
– ref : Cột nào đang sử dụng
– rows : Số hàng (rows) mà MySQL dự đoán phải tìm
– extra : Thông tin phụ, “using temporary” (chưa hiểu) hay “using filesort” (filesort xuất hiện khi lượng dữ liệu trả về là quá lớn hoặc do dùng inner join)

 ANALYZE TABLE tablename;

Những lệnh DELETE và UPDATE để lại rất nhiều những khoảng trống (gaps) vô nghĩa cho table (Đặc biệt là khi bạn dùng kiểu varchar hay text/blob). Điều đó có nghĩa rằng MySQL cũng phải đọc và phân tích những thứ vô nghĩa đó khi query.

Điều này được khắc phục khi bạn chạy  ANALYZE TABLE

Chạy lệnh Analyze TABLE tablename trước và Optimize table tablename sau
Không nên chạy 2 câu lệnh này sau mỗi câu lệnh Insert và update vì nó làm chậm việc thực thi câu lệnh và quan trọng hơn là nó không an toàn cho dữ liệu

Chỉ nên chạy 2 câu này theo định kỳ và do admin thực hiện. Nếu cẩn thận có thể backup database trước khi thực hiện.
Indexing:

Không phải cứ đánh bừa index là có thể tăng tốc độ query vì khi đánh index mySQL sẽ phải sinh ra rất nhiều dữ liệu, vì vậy trước khi đánh index chúng ta nên xem xét tới độ hiệu quả như sau:
Độ hiểu quả = (tổng số dòng trong table)/(tổng số dòng unique trong column)
Độ hiểu quả = count(*) / count(distinct column)

Trong trường hợp bằng 1 (khóa chính) thì đương nhiên đã được tự động index

Dư thừa dữ liệu
Truy vấn trên một bảng sẽ nhanh hơn rất nhiều lần khi truy vấn trên nhiều bảng quan hệ vậy nên đôi khi để tăng tốc độ truy vấn chúng ta phải chấp nhận dư thừa dữ liệu

Chỉ lấy đúng và đủ dữ liệu cần thiết
SELECT a,b thay vì SELECT *
COUNT(1) thay vì COUNT( * )
Dùng mysql_fetch_assoc thay vì mysql_fetch_array vì khi đó hệ thống sẽ trả về một mảng với chỉ số là tên trường, như vậy các bạn sẽ dễ hình dung và đỡ tốn bộ nhớ vì phải phát sinh thêm một mảng với chỉ số dạng số.

Dùng JOIN thay vì subquery:

Như hiện tại trong Pyxis tôi thấy chúng ta dùng tương đối nhiều subquery thay vì thế chúng ta nên dùng JOIN câu query sẽ nhanh hơn

  • PHP
Giải phóng bộ nhớ ngay sau khi sử dụng xong
Theo mặc định thì PHP sẽ giải phóng bộ nhớ sau khi chạy xong toàn bộ chương trình,   using mysql_free_result() sau khi thực hiện các truy vấn và thực hiện xong các phép tính toán với các bản ghi lấy được

Sử dụng phương thức GET cho Ajax

Sử dụng GET thay vì POST bởi vì POST được thực hiện theo 2 bước (gửi header +  gửi data) trong khi GET chỉ gửi 1 gói tin, vậy nếu dung lượng cần gửi <= 2K thì nên dùng GET.

Flush the Buffer Early

<?php flush(); ?>(đặt đoạn này trước thẻ <body>)

Lệnh này cho phép server gửi trước những phần HTML đã sẵn sàng trong khi vẫn tiếp tục xử lý phần còn lại
  • Web server
Lưu trữ phân tán nội dung website vì khi đó chúng ta có thể download đồng thời được nhiều nội dung

ví dụ: nội dung động lưu tại 1 domain www.example.com và 2 domain nữa để lưu nội dung tĩnh static1.example.com, static2.example.com
  • Chế độ ExpiresActive
Ví dụ cho hệ thống Pyxis, lần nào tôi cũng thấy nó download file phông chữ “.woff” vậy tại sao không cache nó theo cách sau:

ExpiresActive On
AddType application/x-font-woff .woff
ExpiresByType application/x-font-woff “access plus 1 year”

ExpiresByType font/woff “access plus 1 month”
ExpiresByType image/jpg “access plus 1 month”
ExpiresByType image/jpeg “access plus 1 month”
ExpiresByType image/gif “access plus 1 month”
ExpiresByType image/png “access plus 1 month”
ExpiresByType text/css “access plus 1 month”
ExpiresByType application/pdf “access plus 1 month”
ExpiresByType text/x-javascript “access plus 1 month”
ExpiresByType application/x-shockwave-flash “access plus 1 month”
ExpiresByType image/x-icon “access plus 1 month”
ExpiresDefault “access plus 2 days”
</IfModule>

Client side:
  • Javascript:
Giảm thiểu việc load javascript file tại thẻ <Head> thay vì đó load ở cuối file

sử dụng http://refresh-sf.com/yui/ để minify những file thư viện, combine nhiều file lại thành 1 file

Nhiều file js không cần thiết load ngay từ đầu nên chúng ta có thể load sau ví dụ: setTimeout(“loadChartPyxisFile();”, 8000);

function loadChartPyxisFile(){
var script = document.createElement(‘script’);
script.src = “js/chartPyxis.js”;
document.getElementsByTagName(‘head’)[0].appendChild(script);
}
  • CSS:
Minify và combine nhiều file CSS lại thành một