Super Speedy Search

How Super Speedy Search Works

Published

This article explains the mechanism behind Super Speedy Search (SSS) at a level that is useful whether you run the shop or write the code. If you just want to get going, start with the Quick Start Guide and Installing and configuring Super Speedy Search. If you want to know why the plugin exists and how it makes search fast, read on.

The problem with default WordPress search

Out of the box, WordPress search is slow and its results are poorly ranked. When someone types a query, WordPress builds a SQL query that looks for the term inside your posts with a condition roughly like post_title LIKE '%term%' OR post_content LIKE '%term%'. If you also search custom fields, it does the same thing against wp_postmeta.

There are two problems with that pattern.

First, it is slow. A LIKE condition with a leading % wildcard cannot use a normal database index. The %term% says “the term can appear anywhere in the text”, so the database has no starting point to look up and is forced to read every row and scan the whole string. That is a full table scan. On a small blog you never notice. On a shop with tens of thousands of products, or a wp_postmeta table with millions of rows, every search reads a large chunk of the database. Under a few concurrent shoppers this piles up and search (and often the whole site) crawls.

Second, the relevance is poor. A LIKE match is all or nothing: a row either contains the string or it does not. There is no score, so WordPress falls back to ordering results by date. A shopper searching for “red wool jumper” gets whatever mentions those words most recently, not the product that matches them best.

The custom index SSS builds instead

Super Speedy Search sidesteps all of that by building its own table, {prefix}superspeedysearch (for example wp_superspeedysearch), and searching that instead of running LIKE against wp_posts and wp_postmeta.

The table is denormalised on purpose. Each row is one indexable item (a post, product, page or other post type you have enabled), and everything you want searched is flattened into that single row: post_title, post_content, post_excerpt, a taxonomydescriptions column holding the terms the item is filed under, a metavalues column holding the custom-field values you chose to search, plus a dedicated column per meta key you add under Search Meta Keys. Because it is all in one row, a search can filter and rank in a single pass rather than joining across posts, postmeta and the taxonomy tables.

On top of those columns SSS creates FULLTEXT indexes: one covering the exact set of columns you enabled (ix_sss_search_columns), plus per-column indexes for title, content, excerpt, taxonomy descriptions and meta values. A FULLTEXT index is the right tool for the job. Unlike a B-tree index it is built for word matching, so the database can find the rows that contain your words without scanning every row, and it returns a relevance score for each match rather than a plain yes or no. See Fulltext Index for how to choose which fields go into it.

At query time SSS runs MATCH(...) AGAINST('...' IN BOOLEAN MODE) against that index. Boolean mode lets the plugin build a precise query from what the shopper typed, requiring the important tokens, allowing prefix matches on the last word (so search updates sensibly as they type), and folding in synonyms.

Rebuilding without disrupting live search

The index is a copy of your content, so it has to be built, and rebuilt when the shape of your data or your settings change. You can trigger a rebuild from the admin UI (Settings > Super Speedy Search > Advanced > Rebuild tables) or from the command line with wp sss rebuild. The CLI runs the same logic without the PHP request timeout and memory limits that kill long rebuilds on shared hosting, so it is the reliable choice on a large catalogue. See Rebuilding Super Speedy Search tables from the command line: wp sss rebuild for the full command reference.

The clever part is that a rebuild never takes live search offline. SSS builds into staging tables, not into the live table:

  1. It creates a staging table, {prefix}superspeedysearch_stage_<key>, with no FULLTEXT indexes, and bulk-inserts all your content into it. Loading data first and indexing afterwards is far faster than maintaining indexes on every insert.
  2. It copies that data into a second table, {prefix}superspeedysearch_temp_<key>, which does carry the FULLTEXT indexes, resolves parent/child relationships, and optimises the table.
  3. Only at the very end does it swap: it drops the old live table and renames the finished temp table over it. That rename is a single, near-instant operation, so shoppers keep searching the old index right up to the moment the new one takes over.
Why this matters

Loading data into an unindexed staging table and building the FULLTEXT index afterwards is far faster than inserting row by row into an already-indexed live table, which would re-index on every insert. The atomic rename at the end is why a rebuild causes zero search downtime, even on a catalogue with millions of rows.

The same staging-and-swap approach builds the companion tables: {prefix}superspeedysearch_terms for taxonomy term matching, the post-title suggestions table, and the taxonomy-combinations table. The rebuild finishes by writing the sss_search_columns option (so the runtime knows which columns are in the index) and flushing the object cache.

As-you-type AJAX versus full-page results

SSS serves two search experiences from the same index.

The as-you-type AJAX panel is the instant drop-down that appears under the search box as a shopper types. It fires a lightweight request to admin-ajax.php on each keystroke (once the query is long enough) and returns a small, ranked set of matches with thumbnails. Using admin-ajax.php matters: page caches and CDNs leave it alone by default, so the per-visitor search request always reaches SSS instead of being served a stale cached page. See Ajax Search Panel – Super Speedy Search Settings and Search Widget for configuring it, and How to add the Super Speedy Search widget into your header for placement.

The full-page search results are the normal search results page a shopper lands on when they submit the form. It uses the same index and ranking but shows a complete, paginated list. See Paginated Search Results, and Searching multiple post types in full-page search results: Single ranked list vs Mixed sections for how results from different post types are laid out.

Relevance, weighting and smart matching

Because the FULLTEXT index returns a score, SSS can rank properly. On top of the raw score it applies your own weights, per column and per post type, at query time. A match in the title can count for more than a match deep in the content, and you can promote a whole post type (say products above blog posts) with a promotion factor. Crucially these weights are applied when the search runs, not baked into the table, so tuning them takes effect immediately with no rebuild. See Adjusting Super Speedy Search Weights.

SSS also handles the messy reality of what people type. Misspellings and synonyms let “couch” find “sofa” and catch common typos, applied at query time (see Misspellings & Synonyms). Taxonomy combination suggestions surface useful category and attribute combinations as a shopper narrows down (see Taxonomy combination suggestions). And SSS searches across as many post types and taxonomies as you enable, so one box covers your whole site.

What triggers a rebuild, and how caching helps

New and changed posts are picked up automatically: SSS hooks into WordPress so that when you add, edit or delete an item, its row in the index is kept in step without a full rebuild. A full rebuild is only needed when the shape of the index itself changes, for example when you toggle which fields are indexed, add a meta key to Search Meta Keys, or change a taxonomy-combination row. Runtime settings, weights, synonyms, templates and caching, apply at query time and never need a rebuild. The rebuild reference article has a full table of what needs one and what does not.

Finally, even a fast index query has a cost, and popular searches run over and over. SSS can track which searches are common and cache the hottest results so those queries are served without touching the index at all. See Analytics & Caching: Track Searches and Cache Hot Results, and Getting Maximum Speed from Super Speedy Search for tuning the whole pipeline for speed.

Further reading

turn this understanding into a tuned, fast search pipeline
serve the most popular searches without touching the index
the hooks, constants and CLI behind the mechanism described here

Comments

▲
▼
1/1