diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php index 54038828..41c231e8 100644 --- a/adminer/include/functions.inc.php +++ b/adminer/include/functions.inc.php @@ -981,6 +981,22 @@ function is_shortable($field) { return ereg('char|text|lob|geometry|point|linestring|polygon', $field["type"]); } +/** Get query to compute number of found rows +* @param string +* @param array +* @param bool +* @param array +* @return string +*/ +function count_rows($table, $where, $is_group, $group) { + global $jush; + $query = " FROM " . table($table) . ($where ? " WHERE " . implode(" AND ", $where) : ""); + return ($is_group && ($jush == "sql" || count($group) == 1) + ? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query" + : "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query$group_by) x" : $query) + ); +} + /** Run query which can be killed by AJAX call after timing out * @param string * @return array of strings diff --git a/adminer/select.inc.php b/adminer/select.inc.php index df3c3af0..621aab86 100644 --- a/adminer/select.inc.php +++ b/adminer/select.inc.php @@ -237,18 +237,14 @@ if (!$columns) { $page = $_GET["page"]; if ($page == "last") { - $query = " FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : ""); - $found_rows = $connection->result($is_group && ($jush == "sql" || count($group) == 1) - ? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query" - : "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query$group_by) x" : $query) - ); + $found_rows = $connection->result(count_rows($TABLE, $where, $is_group, $group)); $page = floor(max(0, $found_rows - 1) / $limit); } $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page); if (!$query) { $query = "SELECT" . limit( - (+$limit && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from, + ($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from, ($where ? "\nWHERE " . implode(" AND ", $where) : "") . $group_by, ($limit != "" ? +$limit : null), ($page ? $limit * $page : 0), @@ -273,12 +269,10 @@ if (!$columns) { } $rows[] = $row; } + // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest) - if ($_GET["page"] != "last") { - $found_rows = (+$limit && $group && $is_group - ? ($jush == "sql" ? $connection->result(" SELECT FOUND_ROWS()") : $connection->result("SELECT COUNT(*) FROM ($query) x")) // space to allow mysql.trace_mode - : count($rows) - ); + if ($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql") { + $found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode } if (!$rows) { @@ -448,13 +442,17 @@ if (!$columns) { if (($rows || $page) && !is_ajax()) { $exact_count = true; - if ($_GET["page"] != "last" && +$limit && !$is_group && ($found_rows >= $limit || $page)) { - $found_rows = found_rows($table_status, $where); - if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) { - // slow with big tables - $found_rows = reset(slow_query("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : ""))); - } else { - $exact_count = false; + if ($_GET["page"] != "last") { + if (!+$limit) { + $found_rows = count($rows); + } elseif ($jush != "sql" || !$is_group) { + $found_rows = ($is_group ? false : found_rows($table_status, $where)); + if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) { + // slow with big tables + $found_rows = reset(slow_query(count_rows($TABLE, $where, $is_group, $group))); + } else { + $exact_count = false; + } } }