Skip to content

Commit

Permalink
[core] simplify counting search results
Browse files Browse the repository at this point in the history
`SELECT images.*` vs `SELECT COUNT(*)`
  • Loading branch information
shish committed Sep 9, 2024
1 parent 38113f3 commit ce44330
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
27 changes: 15 additions & 12 deletions core/imageboard/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ public static function count_images(array $tags = []): int
$total = $cache->get($cache_key);
if (is_null($total)) {
$params = SearchParameters::from_terms($tags);
$querylet = self::build_search_querylet($params);
$total = (int)$database->get_one("SELECT COUNT(*) AS cnt FROM ($querylet->sql) AS tbl", $querylet->variables);
$querylet = self::build_search_querylet($params, count: true);
$total = (int)$database->get_one($querylet->sql, $querylet->variables);
if ($speed_hax && $total > 5000) {
// when we have a ton of images, the count
// won't change dramatically very often
Expand Down Expand Up @@ -275,12 +275,15 @@ private static function tag_or_wildcard_to_ids(string $tag): array
public static function build_search_querylet(
SearchParameters $params,
?int $limit = null,
?int $offset = null
?int $offset = null,
bool $count = false,
): Querylet {
$columns = $count ? "COUNT(*)" : "images.*";

// no tags, do a simple search
if (count($params->tag_conditions) === 0) {
static::$_search_path[] = "no_tags";
$query = new Querylet("SELECT images.* FROM images WHERE 1=1");
$query = new Querylet("SELECT $columns FROM images WHERE 1=1");
}

// one tag sorted by ID - we can fetch this from the image_tags table,
Expand Down Expand Up @@ -311,11 +314,11 @@ public static function build_search_querylet(
if (count($tag_array) == 0) {
// if wildcard expanded to nothing, take a shortcut
static::$_search_path[] = "invalid_tag";
$query = new Querylet("SELECT images.* FROM images WHERE 1=0");
$query = new Querylet("SELECT $columns FROM images WHERE 1=0");
} else {
$set = implode(', ', $tag_array);
$query = new Querylet("
SELECT images.*
SELECT $columns
FROM images INNER JOIN (
SELECT DISTINCT it.image_id
FROM image_tags it
Expand Down Expand Up @@ -350,7 +353,7 @@ public static function build_search_querylet(
# one of the positive tags had zero results, therefor there
# can be no results; "where 1=0" should shortcut things
static::$_search_path[] = "invalid_tag";
return new Querylet("SELECT images.* FROM images WHERE 1=0");
return new Querylet("SELECT $columns FROM images WHERE 1=0");
} elseif ($tag_count == 1) {
// All wildcard terms that qualify for a single tag can be treated the same as non-wildcards
$positive_tag_id_array[] = $tag_ids[0];
Expand All @@ -373,7 +376,7 @@ public static function build_search_querylet(

if ($all_nonexistent_negatives) {
static::$_search_path[] = "all_nonexistent_negatives";
$query = new Querylet("SELECT images.* FROM images WHERE 1=1");
$query = new Querylet("SELECT $columns FROM images WHERE 1=1");
} elseif (!empty($positive_tag_id_array) || !empty($positive_wildcard_id_array)) {
static::$_search_path[] = "some_positives";
$inner_joins = [];
Expand Down Expand Up @@ -407,15 +410,15 @@ public static function build_search_querylet(
$sub_query .= " GROUP BY it.image_id ";

$query = new Querylet("
SELECT images.*
SELECT $columns
FROM images
INNER JOIN ($sub_query) a on a.image_id = images.id
");
} elseif (!empty($negative_tag_id_array)) {
static::$_search_path[] = "only_negative_tags";
$negative_tag_id_list = join(', ', $negative_tag_id_array);
$query = new Querylet("
SELECT images.*
SELECT $columns
FROM images
LEFT JOIN image_tags negative ON negative.image_id = images.id AND negative.tag_id in ($negative_tag_id_list)
WHERE negative.image_id IS NULL
Expand Down Expand Up @@ -447,11 +450,11 @@ public static function build_search_querylet(
$query->append(new Querylet($img_sql, $img_vars));
}

if (!is_null($params->order)) {
if (!is_null($params->order) && $count === false) {
$query->append(new Querylet(" ORDER BY ".$params->order));
}

if (!is_null($limit)) {
if (!is_null($limit) && $count == false) {
$query->append(new Querylet(" LIMIT :limit ", ["limit" => $limit]));
$query->append(new Querylet(" OFFSET :offset ", ["offset" => $offset]));
}
Expand Down
1 change: 1 addition & 0 deletions ext/index/main.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public function onCliGen(CliGenEvent $event): void
$params,
$limit,
(int)(($page - 1) * $limit),
$count,
);

$sql_str = $q->sql;
Expand Down

0 comments on commit ce44330

Please sign in to comment.