【问题标题】:mysql Query slow - IP lookup (banned or not)mysql 查询慢 - IP 查找(禁止与否)
【发布时间】:2011-12-20 05:29:46
【问题描述】:

我的 PHP 文件中有一个检查 IP 是否被禁止的函数。由于某种原因,我的网站非常慢,问题是当我检查 IP 是否被禁止时。

(我删除了检查的代码,我的网站又快了)

这是我的代码:

// 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

这是我的功能

// 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;
}

运行此查询大约需要 2 到 3 秒。为什么?我没有离开联接或其他表。

谢谢

【问题讨论】:

    标签: php mysql performance ip


    【解决方案1】:
    1. IP 列上放置一个(唯一?)索引
    2. 通过将文本表示转换为“本机”表示来使用正确的数据类型(ipv4 适合INT UNSIGNED,ipv6 适合 2BIGINT UNSIGNED):这将使您的表更小,并且需要更少的 I/ O 扫描期间

    另外,即使$_SERVER["REMOTE_ADDR"] 应该是安全的,永远不要忘记转义 SQL 查询中的数据!

    【讨论】:

    • 1.1.1.1不是整数,怎么会有INT作为数据类型?
    • @Gino 查找 ip2longlong2ip PHP 函数或 INET_ATON()INET_NTOA() MySQL 函数
    • INT 查找速度比 CHAR(20) 快吗?
    • @Col.Shrapnel 经过一番挖掘,我发现不建议使用 varchar/char 进行查找,INT 更好。另外,我发现使用了一系列 IP,而不是寻找每个单独的 IP(例如,1.1.1.1 到 1.1.1.255,而是 > upperboundIP INT 编号)。所以更容易个人维护。 -CodeCaster 有一个很好的解决方案,但我认为不推荐使用 2 个 IP 表
    • @Col.Shrapnel 这就是为什么使用正确的索引是我列表中的第 1 点...第二个只是一个补充(但是,根据我的经验,有时这种数据类型问题会导致大量减速;参见例如stackoverflow.com/questions/4777070/…)
    【解决方案2】:

    在 ip 列上放一个索引。

    网络上有大量关于查询分析和改进的信息,所以我不会为您重复这些信息,但索引绝对会有所帮助。

    我猜security.ip 是一个非常大的表,所以查找变得很慢。

    索引的缺点:写入变得有点慢,所以如果你在那个表上写了很多,你可以尝试将禁止部分卸载到一个新表,比如banned_ips

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-22
      • 2012-06-01
      • 2014-01-27
      相关资源
      最近更新 更多