2011-11-02 10 views
16

Tôi có trên tệp PHP của tôi một chức năng kiểm tra xem một IP có bị cấm hay không. Đối với một số lý do trang web của tôi là rất chậm và vấn đề là khi tôi kiểm tra xem IP bị cấm hay không.Truy vấn mysql chậm - tra cứu IP (bị cấm hay không)

(tôi loại bỏ mã để kiểm tra và trang web của tôi đã nhanh chóng trở lại)

Dưới đây là mã của tôi:

// index.php - everything redirects to this file in the .htaccess 
<?php 
include('config.php'); 
if(isIpBanned($_SERVER['REMOTE_ADDR'])) { 
die('access denied'); 
} 
// rest of the code 

đây là chức năng của tôi

// config.php 
<?php 
function isIpBanned($db, $ip) { // $db is declared correctly 
$goodIP = $db->getRecord("SELECT is_banned FROM security.ip WHERE ip = '$ip'"); // this function works and return 1 or 0 
return (bool)$goodIP; 
} 

Truy vấn này mất khoảng 2 giây để 3 giây để chạy. Tại sao? Tôi không có tham gia hoặc các bảng khác.

Cảm ơn

Trả lời

26
  1. Đặt một (duy nhất?) Chỉ số trên IP cột
  2. Sử dụng kiểu dữ liệu chính xác bằng cách chuyển đổi các đại diện văn bản thành một "bản địa" (một ipv4 phù hợp trong một INT UNSIGNED, một ipv6 trong 2 BIGINT UNSIGNED): điều này sẽ làm cho bảng của bạn nhỏ hơn, và sẽ đòi hỏi ít I/O trong quá trình quét

và, như một mặt lưu ý, ngay cả khi $_SERVER["REMOTE_ADDR"] nên được an toàn, KHÔNG BAO GIỜ QUÊN để thoát dữ liệu trong SQL VƯỚNG MẮC!

+0

1.1.1.1 không phải là trình kết nối, làm thế nào bạn có thể có INT làm kiểu dữ liệu? –

+0

@Gino tra cứu hàm PHP 'ip2long' và' long2ip' hoặc hàm 'INET_ATON()' và 'INET_NTOA()' của hàm – CAFxX

+0

INT nhanh hơn CHAR (20) để tra cứu? –

2

Đặt chỉ mục trên cột ip.

Có rất nhiều thông tin trên web khi phân tích truy vấn và cải thiện vì vậy tôi sẽ không lặp lại điều đó cho bạn, nhưng một chỉ mục chắc chắn sẽ giúp ích nhiều nhất.

Tôi đoán security.ip là một bảng rất lớn, vì vậy tra cứu trở nên chậm.

Hạn chế của chỉ mục: viết trở nên chậm hơn một chút, vì vậy nếu bạn viết nhiều vào bảng đó, bạn có thể cố gắng dỡ phần cấm trong một bảng mới, nói banned_ips.