【问题标题】:How Can I make this MySQL Count query more efficient?如何使这个 MySQL Count 查询更高效?
【发布时间】:2011-05-19 00:27:37
【问题描述】:
//get the current member count
$sql = ("SELECT count(member_id) as total_members from exp_members");
$result = mysql_query($sql) or die(mysql_error());
$num_rows = mysql_num_rows($result);
if ($num_rows != 0) {
    while($row = mysql_fetch_array($result)) {
        $total_members = $row['total_members'];
    }
}

//get list of products
$sql = ("SELECT m_field_id, m_field_label from exp_member_fields where m_field_name like 'cf_member_ap_%' order by m_field_id asc");
$result = mysql_query($sql) or die(mysql_error());
$num_rows = mysql_num_rows($result);

if ($num_rows != 0) {

    while($row = mysql_fetch_array($result)) {

        $m_field_id             = $row['m_field_id'];
        $m_field_label          = $row['m_field_label'];

        $sql2 = ("SELECT count(m_field_id_".$m_field_id.") as count from exp_member_data where m_field_id_".$m_field_id." = 'y'");
        $result2 = mysql_query($sql2) or die(mysql_error());
        $num_rows2 = mysql_num_rows($result2);

        if ($num_rows2 != 0) {
            while($row2 = mysql_fetch_array($result2)) {
                $p = ($row2['count']/$total_members)*100;
                $n = $row2['count'];
                $out .= '<tr><td>'.$m_field_label.'</td><td>'.number_format($p,1).'%</td><td>'.$n.'</td></tr>';
            }
        }

    }


}

【问题讨论】:

  • 你的表定义是什么(包括索引)?

标签: php mysql count


【解决方案1】:

如果您可以用非代码术语描述您想要完成的工作,那么提供帮助会更容易。但问题的一个指标是在一个查询的行上看到一个 php 循环,而对每一行执行另一个查询。

有多种方法可以查询小计。但是如果你能稍微解释一下目标会更容易解释。

【讨论】:

  • 我想我想尝试改进的部分是获取产品列表,然后对每个产品运行查询以获取在该产品列中具有“y”的用户数。它本身并没有运行缓慢,它很好,我们正在缓存结果。我只是想知道是否可以减少系统的密集度。
  • 基本上在 exp_member_data 表中,我们有带有 member_id 的行,显然每个成员有 1 行。大约有300,000名成员。在同一个表中是每个产品的列。如果单元格不使用或确实使用该产品,则单元格会说“n”或“y”。
  • 产品名称位于名为 exp_member_fields 的表中。此表中的每一行代表一个自定义成员字段。因此,我想从该表中获取代表产品的所有行的唯一 ID (X) 以及产品标签,然后从列 (m_field_id_X) 所在的 exp_member_data 表中获取带有“y”的行数与 exp_member_fields 表中的行 ID 相关。
【解决方案2】:

count 查询总是返回 1 行,所以你不需要循环

$sql = ("SELECT count(member_id) as total_members from exp_members");
$result = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($result);
$total_members = $row['total_members'];

除此之外,我不确定您如何才能使它变得更好。您可以对两个计数查询执行相同的操作。

由于这些是直截了当的查询,我猜现在的任何瓶颈都在 MySQL 端

【讨论】:

    【解决方案3】:

    第一个 COUNT 查询(“获取当前成员数”)应该几乎立即执行。

    第二个查询(“获取产品列表”)可能会很慢,具体取决于您的索引。您在 m_field_name 上进行查询,然后在 m_field_id 上进行排序,因此您可能需要两者的组合索引。

    第三个查询重复执行(每个产品一次),查询m_field_id_*(即许多可能的字段中的任何一个),因此您可能应该确保它们已被索引。

    总而言之,您需要 a) 找出哪个查询运行缓慢,b) 为需要索引的内容编制索引,以及 c) 如果可能,合并查询。

    【讨论】:

    • 在任何查询中都没有 m_field_id_*
    • 星号 (*) 是“通配符”或“匹配任何内容”的常用简写。您的查询中有这个:m_field_id_".$m_field_id
    猜你喜欢
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    相关资源
    最近更新 更多