From 6d1c7c414b694c31e44ba3c88d94a8f0a2ae1e19 Mon Sep 17 00:00:00 2001 From: Daku Date: Fri, 4 Dec 2015 11:38:44 +0000 Subject: [PATCH] mysql < 5.6 has terrible subquery optimization, using EXISTS / JOIN fixes this --- core/imageboard.pack.php | 19 ++++++++++++++++--- ext/index/main.php | 20 ++++++++++++++------ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index e27bc7a0..1d8365f7 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -560,9 +560,22 @@ class Image { */ public function delete_tags_from_image() { global $database; - $database->execute( - "UPDATE tags SET count = count - 1 WHERE id IN ". - "(SELECT tag_id FROM image_tags WHERE image_id = :id)", array("id"=>$this->id)); + if($database->get_driver_name() == "mysql") { + //mysql < 5.6 has terrible subquery optimization, using EXISTS / JOIN fixes this + $database->execute(" + UPDATE tags t + INNER JOIN image_tags it ON t.id = it.tag_id + SET count = count - 1 + WHERE it.image_id = :id", + array("id"=>$this->id) + ); + } else { + $database->execute(" + UPDATE tags + SET count = count - 1 + WHERE id IN (SELECT tag_id FROM image_tags WHERE image_id = :id)", array("id"=>$this->id) + ); + } $database->execute("DELETE FROM image_tags WHERE image_id=:id", array("id"=>$this->id)); } diff --git a/ext/index/main.php b/ext/index/main.php index 75a7fab0..78404fe6 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -253,9 +253,9 @@ class Index extends Extension { $search_terms = $event->get_search_terms(); $page_number = $event->get_page_number(); $page_size = $event->get_page_size(); - + $count_search_terms = count($search_terms); - + try { #log_debug("index", "Search for ".implode(" ", $search_terms), false, array("terms"=>$search_terms)); $total_pages = Image::count_pages($search_terms); @@ -277,7 +277,7 @@ class Index extends Extension { } $count_images = count($images); - + if($count_search_terms === 0 && $count_images === 0 && $page_number === 1) { $this->theme->display_intro($page); send_event(new PostListBuildingEvent($search_terms)); @@ -322,8 +322,17 @@ class Index extends Extension { // check for tags first as tag based searches are more common. if(preg_match("/^tags([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) { $cmp = ltrim($matches[1], ":") ?: "="; - $tags = $matches[2]; - $event->add_querylet(new Querylet('images.id IN (SELECT DISTINCT image_id FROM image_tags GROUP BY image_id HAVING count(image_id) '.$cmp.' '.$tags.')')); + $count = $matches[2]; + $event->add_querylet( + new Querylet("EXISTS ( + SELECT 1 + FROM image_tags it + LEFT JOIN tags t ON it.tag_id = t.id + WHERE images.id = it.image_id + GROUP BY image_id + HAVING COUNT(*) $cmp $count + )") + ); } else if(preg_match("/^ratio([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+):(\d+)$/i", $event->term, $matches)) { $cmp = preg_replace('/^:/', '=', $matches[1]); @@ -394,4 +403,3 @@ class Index extends Extension { $this->stpen++; } } -