Danbooru

Tag autocompletion should include aliased tags

Posted under Bugs & Features

tl;dr: Tag aliases do their work when a search is submitted or an edit is committed, and that was adequate back when we didn't have a tag autocompletion feature. Now that we have autocomplete, tag aliases should be integrated into autocomplete candidates. This is both a QoL improvement as well as a feature that aims to mitigate some types of common mistagging.

-----

So here's a couple of motivating use cases to start with:

1.
For the longest time, wink has been aliased to one_eye_closed.
Then winking was introduced to cover animated cases.
That's all fine and good, except winking is commonly misused on non-animated posts, instead of one_eye_closed, in spite of the addition of specific caution against it in the wiki.
(I've been periodically housekeeping using a -winking wink tag script on winking -animated, so you won't see many examples.)

2.
v is the 'victory' or 'peace' hand sign: raised index and middle fingers. v_sign and peace_sign are aliased to it.
peace_symbol is the circular symbol ☮ originally made for the Campaign for Nuclear Disarmament.
Instances of the handsign are periodically mistagged with peace_symbol.
(Again, I've been cleaning those up, so you won't find any.)

It's worth noting that Contributor- and Builder-level are making these mistaggings too, it is not purely a "noob mistake".

Sure, people not knowing the right tags / not reading wiki definitions is kind of an unsolvable perennial problem, but something else happened that got me thinking: I have an old habit of tagging wink on static images and letting the tag alias handle the conversion to one_eye_closed, but then one time I inadvertently hit the tab key while editing and wink autocompleted to winking, resulting in mistagging. (Note that aliased tags, e.g. wink are not listed as an autocomplete option.) It occurred to me that autocompletion may be contributing to the problem; after all, it is not surprising that user behavior tends toward trusting autocompletion systems in situations like this, i.e. "Oh hey, there's a tag that looks like what I want!"

A solution, I think, is to include aliased tags in the list of autocompletion candidates. Both the source and target tags of the alias should be displayed, and sort order should be post count of the target tag. Indicate the alias as a note, and the aliased tag could have grayed out color (better) or strikethrough formatting (less legible, but used here to illustrate examples, since DText doesn't do color):

wink (aliased to one_eye_closed)

winkone_eye_closed

This way, when a user inputs "wink", autocomplete suggests first "wink → one_eye_closed", then "winking"; when "peace" is input, "peace_sign → v" comes up together with "peace_symbol". The idea is that users will see both options and do a double take, and hopefully this encourages them to look up the wiki to make sure the have the right tag.

Of course, this would work for tag autocompletion in search as well, and not just when editing.

There are two possibilities for handling the input completion:

  • Autocomplete allows the source tag, so "wink" will autocomplete as "wink", and the alias system takes over as it currently does when the form is submitted, or
  • The alias kicks in on the fly during input, replacing the source tag "wink" with the target tag "one_eye_closed" when selected for autocompletion.

Both options have pros and cons, and the latter one would likely involve a bit more work to implement. Which way is better is up for discussion.

Besides mitigating such mistagging use cases, this feature would of course also be a quality of life improvement:

  • One of the goals of the tag aliasing mechanism is to ensure that when a tag is renamed, users will still be able to locate posts by searching the old tag; this worked before with explicit input but bringing aliased tags to search box autocomplete will make it as equally convenient as normal tags.
  • It would also be helpful when using slash-shortcut tags to have visual confirmation of the target tag. Good for avoiding typos with similar tags such as /t vs /tr; nice to have in general e.g. /hrhakurei_reimu

Thoughts?

Even if you manage to convince Albert that it's worth it I want to point out that the order's going to be messed up for these. Aliased tags will always appear last because they have 0 post count.

So for example if you typed "peace" in autocomplete, the peace_sign -> v line would be in 16th place since peace_sign has 0 posts and not show up at all since autocomplete only shows 10 results at a time. Despite the consequent v having 17847 posts.

Some would still show up though at least. If you typed "wink" then wink -> one_eye_closed would be in 3rd place, and if you typed "/hr" then /hr -> hakurei_reimu would be first place.

@Toks: that is, unless we do a left join alias table on actual tag table to get the count. This could be pretty expensive, though it shouldn't be THAT expensive - tag/alias ratio is about 5/1, and even non-left-anchored queries on tag table run fine (stuff like *_dress works on autocomplete, too!), so it should be fine.

Also, it will not work if we have alias chains. Do we have any, by the way? E.g. A aliased to B, B aliased to C, instead of both A and B aliased to C.

On a second thought, certain aliases should be filtered out from the list. If both tag and alias match the expression entered so far, only one (primary tag) should be shown in autocomplete list. Otherwise, when typing 'zomb' we will get zombie_pose, zombie (primary), and zombies (alias) in that order, before other zombie-related tags.

Luckily, filtering out is easy enough (select from alias where alias like query and tag not like query), but it will further affect performance.

Type-kun said:

@Toks: that is, unless we do a left join alias table on actual tag table to get the count. This could be pretty expensive, though it shouldn't be THAT expensive - tag/alias ratio is about 5/1, and even non-left-anchored queries on tag table run fine (stuff like *_dress works on autocomplete, too!), so it should be fine.

I already tried doing two joins to get the consequent post count but it seems real slow. This is what I tried:

Two joins

Query:

SELECT tags.*, tag_aliases.consequent_name,
  CASE WHEN t2.post_count IS NULL THEN tags.post_count ELSE t2.post_count END AS post_count_or_consequent_post_count
  FROM "tags"
LEFT JOIN tag_aliases ON tags.name = tag_aliases.antecedent_name
LEFT JOIN tags AS t2 ON t2.name = tag_aliases.consequent_name
WHERE (true) AND (tags.name LIKE 's%' ESCAPE E'\\')
ORDER BY post_count_or_consequent_post_count desc
LIMIT 20

Explain:

Limit  (cost=49829.70..49829.75 rows=20 width=183)
  ->  Sort  (cost=49829.70..49968.94 rows=55697 width=183)
        Sort Key: (CASE WHEN (t2.post_count IS NULL) THEN tags.post_count ELSE t2.post_count END)
        ->  Hash Left Join  (cost=33197.63..48347.62 rows=55697 width=183)
              Hash Cond: (tags.name = tag_aliases.antecedent_name)
              ->  Bitmap Heap Scan on tags  (cost=1765.85..16140.32 rows=55697 width=165)
                    Filter: (name ~~ 's%'::text)
                    ->  Bitmap Index Scan on index_tags_on_name_pattern  (cost=0.00..1751.93 rows=55157 width=0)
                          Index Cond: ((name ~>=~ 's'::text) AND (name ~<~ 't'::text))
              ->  Hash  (cost=31322.70..31322.70 rows=8726 width=31)
                    ->  Hash Left Join  (cost=27901.73..31322.70 rows=8726 width=31)
                          Hash Cond: ((tag_aliases.consequent_name)::text = t2.name)
                          ->  Seq Scan on tag_aliases  (cost=0.00..210.26 rows=8726 width=27)
                          ->  Hash  (cost=18697.77..18697.77 rows=501277 width=17)
                                ->  Seq Scan on tags t2  (cost=0.00..18697.77 rows=501277 width=17)

Looks like it has to sequential scan tags (t2) when getting the consequent post counts.

I might just be doing something terribly wrong, admittedly. Do you know of a way to optimize it?

For reference, here's how it currently is (orders of magnitude faster than the two joins):

Normal

Query:

SELECT "tags".* FROM "tags"
WHERE (true)
AND (name LIKE 's%' ESCAPE E'\\')
ORDER BY post_count desc
LIMIT 20

Explain:

Limit  (cost=0.00..16.87 rows=20 width=165)
  ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..46971.54 rows=55697 width=165)
        Filter: (name ~~ 's%'::text)

And here's how it would be if we joined with tag_aliases, but didn't do the second join:

Single join

Query:

SELECT tags.*, tag_aliases.consequent_name
  FROM "tags"
LEFT JOIN tag_aliases ON tags.name = tag_aliases.antecedent_name
WHERE (true) AND (tags.name LIKE 's%' ESCAPE E'\\')
ORDER BY post_count desc
LIMIT 20

Explain:

Limit  (cost=0.00..22.70 rows=20 width=179)
  ->  Nested Loop Left Join  (cost=0.00..63218.40 rows=55697 width=179)
        ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..46971.54 rows=55697 width=165)
              Filter: (name ~~ 's%'::text)
        ->  Index Scan using index_tag_aliases_on_antecedent_name on tag_aliases  (cost=0.00..0.28 rows=1 width=27)
              Index Cond: (tags.name = antecedent_name)

Perhaps just update the antecedent post count regularly rather than the costly join to obtain the real-time correct tag count? Like subscription updating job. Should still sort well enough based on an approximate count, I think.

r0d3n7z said:

Perhaps just update the antecedent post count regularly rather than the costly join to obtain the real-time correct tag count? Like subscription updating job. Should still sort well enough based on an approximate count, I think.

Could work, but would likely have unintended consequences. The site assumes that aliased tags have 0 post count so giving them a fake post count might result in some weird bugs.

One of the them off the top of my head is the artist search option search[empty_only]=true. It's supposed to return artist entries with 0 posts. But if this change was made then it would no longer return ones that have 0 posts due to an alias. There are probably going to be a lot of little bugs like this that would add up to be fairly bad.

Also, tag corrections would try to set the post count back to the real value (0), so there'd need to be a special case to prevent that from happening.

I might just be doing something terribly wrong, admittedly. Do you know of a way to optimize it?

I wrote a lengthy post first, and then understood you're just querying the aliases count, not combining the results yet. I think there's no need to join tags the third time, just the main condition should run against antecedent_name. Anyway, try to execute the second query this way to see the cost and if tag counts are actual. It depends on the way tags.antecedent_name is indexed; it seems to have `index_tag_aliases_on_antecedent_name`, but I remember postgres being picky about left-anchored likes. Also, I just realized there's no need for left_join, inner_join will do. It probably will be slower than regular query on tags, because it uses index on post_count and filters it on name instead of searching by name and ordering by post_count. Postgres is pretty damn smart :3

SELECT tags.*, tag_aliases.antecedent_name, tag_aliases.consequent_name
  FROM "tag_aliases"
INNER JOIN tags ON tags.name = tag_aliases.consequent_name
WHERE (tag_aliases.antecedent_name LIKE 's%' ESCAPE E'\\')
ORDER BY post_count desc
LIMIT 20

Toks said:

Could work, but would likely have unintended consequences. The site assumes that aliased tags have 0 post count so giving them a fake post count might result in some weird bugs.

Another way to take care of that, in case optimizing a join fails, would be to denormalize tables a bit, and include post_count column into tag_aliases table, and introduce on-update trigger on tag table, which would synchronize post counts on tags.name and tag_aliases.consequent_name.

Type-kun said:

I wrote a lengthy post first, and then understood you're just querying the aliases count, not combining the results yet. I think there's no need to join tags the third time, just the main condition should run against antecedent_name. Anyway, try to execute the second query this way to see the cost and if tag counts are actual. It depends on the way tags.antecedent_name is indexed; it seems to have `index_tag_aliases_on_antecedent_name`, but I remember postgres being picky about left-anchored likes. Also, I just realized there's no need for left_join, inner_join will do. It probably will be slower than regular query on tags, because it uses index on post_count and filters it on name instead of searching by name and ordering by post_count. Postgres is pretty damn smart :3

SELECT tags.*, tag_aliases.antecedent_name, tag_aliases.consequent_name
  FROM "tag_aliases"
INNER JOIN tags ON tags.name = tag_aliases.consequent_name
WHERE (tag_aliases.antecedent_name LIKE 's%' ESCAPE E'\\')
ORDER BY post_count desc
LIMIT 20

Hmm. But that doesn't return all results. It only returns tags that have aliases. Something like solo with no aliases is excluded. I guess we could make two queries and combine the results of the two afterwards with ruby code but this seems hacky so I'm not a fan.

I checked the performance anyway and it's still slow, taking more than a second for common queries like these.

Inner join

Explain for query s*

Limit  (cost=0.00..3846.98 rows=20 width=192)
  ->  Nested Loop  (cost=0.00..169651.69 rows=882 width=192)
        ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..44748.13 rows=436596 width=165)
        ->  Index Scan using index_tag_aliases_on_consequent_name on tag_aliases  (cost=0.00..0.28 rows=1 width=27)
              Index Cond: ((consequent_name)::text = tags.name)
              Filter: (antecedent_name ~~ 's%'::text)

Explain for query c*

Limit  (cost=4454.62..4454.67 rows=20 width=192)
  ->  Sort  (cost=4454.62..4455.94 rows=529 width=192)
        Sort Key: tags.post_count
        ->  Nested Loop  (cost=0.00..4440.54 rows=529 width=192)
              ->  Seq Scan on tag_aliases  (cost=0.00..232.11 rows=529 width=27)
                    Filter: (antecedent_name ~~ 'c%'::text)
              ->  Index Scan using index_tags_on_name on tags  (cost=0.00..7.95 rows=1 width=165)
                    Index Cond: (name = (tag_aliases.consequent_name)::text)

You'll notice the index_tag_aliases_on_antecedent_name you mentioned is not getting used. That's because it seems to only works for = queries, not LIKE. However, even after adding a new index_tag_aliases_on_antecedent_name_pattern it barely improves at all:

Show
Limit  (cost=4369.81..4369.86 rows=20 width=192)
  ->  Sort  (cost=4369.81..4371.13 rows=529 width=192)
        Sort Key: tags.post_count
        ->  Nested Loop  (cost=17.68..4355.74 rows=529 width=192)
              ->  Bitmap Heap Scan on tag_aliases  (cost=17.68..147.31 rows=529 width=27)
                    Filter: (antecedent_name ~~ 'c%'::text)
                    ->  Bitmap Index Scan on index_tag_aliases_on_antecedent_name_pattern  (cost=0.00..17.55 rows=530 width=0)
                          Index Cond: ((antecedent_name ~>=~ 'c'::text) AND (antecedent_name ~<~ 'd'::text))
              ->  Index Scan using index_tags_on_name on tags  (cost=0.00..7.95 rows=1 width=165)
                    Index Cond: (name = (tag_aliases.consequent_name)::text)

Toks said:

Hmm. But that doesn't return all results. It only returns tags that have aliases. Something like solo with no aliases is excluded. I guess we could make two queries and combine the results of the two afterwards with ruby code but this seems hacky so I'm not a fan.

That's expected; next step is just to do a union query with "normal" query to tags table - or, preferably, "union all" query which will sum query costs instead of multiplying them. Also, combining two result sets doesn't seems all that hacky to me (query 20 results from both aliases and tags, then filter out duplicates if any), but either way it is unusable unless we get tag_alias query to run faster.

Anyway, the "Normal" query on tags works faster because of 'LIMIT' clause and order by post_count - see how it uses 'index_tags_on_post_count' to fetch some rows in order of post_count and then filter what it fetched by "like" condition specified, until it gets enough rows to terminate execution. What confuses me is that it should get much slower as your query gets more obscure, because it would have to go through entire index to get enough rows. What does plan say if you query for something like [%? does it use index_tags_on_name_pattern instead?

Either way, join query against tag aliases doesn't have post count info, so it has to find all suitable aliases firsts (either via seq scan or new index introduced), then join all suitable rows from `tags` to get counts, and then sort on them(that's what happens for c%); or do it backwards, and fetch rows from tags in post order, then join tag_aliases rows to them to get alias name, and then filter on it (that's what happens for s%). I see the only way to circumvent that - denormailze the tables as I mentioned earlier, so that post count is stored in tag_aliases table, updated either via job or trigger. If an index is created on that column, query against tag_aliases will run exactly the same way as it is run against `tags` table. It shouldn't even be that hard on database, actually, especially if done as a job.

Type-kun said:

That's expected; next step is just to do a union query with "normal" query to tags table - or, preferably, "union all" query which will sum query costs instead of multiplying them. Also, combining two result sets doesn't seems all that hacky to me (query 20 results from both aliases and tags, then filter out duplicates if any), but either way it is unusable unless we get tag_alias query to run faster.

Oh, so we can combine them in sql instead of ruby. That seems less hacky.

Union all

Query:

SELECT DISTINCT ON (name, post_count) * FROM
(
  (
    SELECT "tags".*, null AS antecedent_name, null AS consequent_name FROM "tags"
    WHERE (name LIKE 's%' ESCAPE E'\\')
    ORDER BY post_count desc
    LIMIT 20
  )

  UNION ALL

  (
    SELECT tags.*, tag_aliases.antecedent_name, tag_aliases.consequent_name FROM "tag_aliases"
    INNER JOIN tags ON tags.name = tag_aliases.consequent_name
    WHERE (tag_aliases.antecedent_name LIKE 's%' ESCAPE E'\\')
    AND (tags.name NOT LIKE 's%' ESCAPE E'\\')
    ORDER BY post_count desc
    LIMIT 20
  )
) AS unioned_query
ORDER BY post_count desc
LIMIT 10

Explain:

Limit  (cost=4023.98..4024.06 rows=10 width=211)
  ->  Unique  (cost=4023.98..4024.28 rows=40 width=211)
        ->  Sort  (cost=4023.98..4024.08 rows=40 width=211)
              Sort Key: public.tags.post_count, public.tags.name
              ->  Result  (cost=0.00..4022.92 rows=40 width=211)
                    ->  Append  (cost=0.00..4022.92 rows=40 width=211)
                          ->  Limit  (cost=0.00..18.90 rows=20 width=165)
                                ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..45839.62 rows=48511 width=165)
                                      Filter: (name ~~ 's%'::text)
                          ->  Limit  (cost=0.00..4003.62 rows=20 width=192)
                                ->  Nested Loop  (cost=0.00..156941.80 rows=784 width=192)
                                      ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..45839.62 rows=388085 width=165)
                                            Filter: (name !~~ 's%'::text)
                                      ->  Index Scan using index_tag_aliases_on_consequent_name on tag_aliases  (cost=0.00..0.28 rows=1 width=27)
                                            Index Cond: ((consequent_name)::text = public.tags.name)
                                            Filter: (antecedent_name ~~ 's%'::text)

Still on the slow side but at least it's fully functional now (I added the duplicate filtering to it too).

Type-kun said:

Anyway, the "Normal" query on tags works faster because of 'LIMIT' clause and order by post_count - see how it uses 'index_tags_on_post_count' to fetch some rows in order of post_count and then filter what it fetched by "like" condition specified, until it gets enough rows to terminate execution. What confuses me is that it should get much slower as your query gets more obscure, because it would have to go through entire index to get enough rows. What does plan say if you query for something like [%? does it use index_tags_on_name_pattern instead?

Yes

Normal for [%

Query:

SELECT "tags".* FROM "tags"
WHERE (true)
AND (name LIKE '[%' ESCAPE E'\\')
ORDER BY post_count desc
LIMIT 20

Explain:

Limit  (cost=9.55..9.60 rows=20 width=165)
  ->  Sort  (cost=9.55..9.66 rows=44 width=165)
        Sort Key: post_count
        ->  Index Scan using index_tags_on_name_pattern on tags  (cost=0.00..8.38 rows=44 width=165)
              Index Cond: ((name ~>=~ '['::text) AND (name ~<~ '\'::text))
              Filter: (name ~~ '[%'::text)

While we're here I'll point out that obscure searches like [% perform well even with the queries that include aliases.

Union all for [%

Query:

SELECT DISTINCT ON (name, post_count) * FROM
(
  (
    SELECT "tags".*, null AS antecedent_name, null AS consequent_name FROM "tags"
    WHERE (name LIKE '[%' ESCAPE E'\\')
    ORDER BY post_count desc
    LIMIT 10
  )

  UNION ALL

  (
    SELECT tags.*, tag_aliases.antecedent_name, tag_aliases.consequent_name FROM "tag_aliases"
    INNER JOIN tags ON tags.name = tag_aliases.consequent_name
    WHERE (tag_aliases.antecedent_name LIKE '[%' ESCAPE E'\\')
    AND (tags.name NOT LIKE '[%' ESCAPE E'\\')
    ORDER BY post_count desc
    LIMIT 10
  )
) AS unioned_query
ORDER BY post_count desc
LIMIT 10

Explain:

Limit  (cost=26.34..26.41 rows=10 width=226)
  ->  Unique  (cost=26.34..26.42 rows=11 width=226)
        ->  Sort  (cost=26.34..26.36 rows=11 width=226)
              Sort Key: public.tags.post_count, public.tags.name
              ->  Result  (cost=9.33..26.15 rows=11 width=226)
                    ->  Append  (cost=9.33..26.15 rows=11 width=226)
                          ->  Limit  (cost=9.33..9.36 rows=10 width=165)
                                ->  Sort  (cost=9.33..9.44 rows=44 width=165)
                                      Sort Key: public.tags.post_count
                                      ->  Index Scan using index_tags_on_name_pattern on tags  (cost=0.00..8.38 rows=44 width=165)
                                            Index Cond: ((name ~>=~ '['::text) AND (name ~<~ '\'::text))
                                            Filter: (name ~~ '[%'::text)
                          ->  Limit  (cost=16.67..16.68 rows=1 width=192)
                                ->  Sort  (cost=16.67..16.68 rows=1 width=192)
                                      Sort Key: public.tags.post_count
                                      ->  Nested Loop  (cost=0.00..16.66 rows=1 width=192)
                                            ->  Index Scan using index_tag_aliases_on_antecedent_name_pattern on tag_aliases  (cost=0.00..8.27 rows=1 width=27)
                                                  Index Cond: ((antecedent_name ~>=~ '['::text) AND (antecedent_name ~<~ '\'::text))
                                                  Filter: (antecedent_name ~~ '[%'::text)
                                            ->  Index Scan using index_tags_on_name on tags  (cost=0.00..8.38 rows=1 width=165)
                                                  Index Cond: (name = (tag_aliases.consequent_name)::text)
                                                  Filter: (name !~~ '[%'::text)

Type-kun said:

Either way, join query against tag aliases doesn't have post count info, so it has to find all suitable aliases firsts (either via seq scan or new index introduced), then join all suitable rows from `tags` to get counts, and then sort on them(that's what happens for c%); or do it backwards, and fetch rows from tags in post order, then join tag_aliases rows to them to get alias name, and then filter on it (that's what happens for s%). I see the only way to circumvent that - denormailze the tables as I mentioned earlier, so that post count is stored in tag_aliases table, updated either via job or trigger. If an index is created on that column, query against tag_aliases will run exactly the same way as it is run against `tags` table. It shouldn't even be that hard on database, actually, especially if done as a job.

Seems to help quite a bit. This might be fast enough now.

Show

Query:

SELECT DISTINCT ON (name, post_count) * FROM
(
  (
    SELECT tags.name, tags.post_count, tags.category, null AS antecedent_name, null AS consequent_name FROM "tags"
    WHERE (true) AND (name LIKE 's%' ESCAPE E'\\')
    AND (post_count > 0)
    ORDER BY post_count desc LIMIT 20
  )
  UNION ALL
  (
    SELECT tags.name, tag_aliases.post_count, tags.category, tag_aliases.antecedent_name, tag_aliases.consequent_name FROM "tag_aliases"
    INNER JOIN tags ON tags.name = tag_aliases.consequent_name
    WHERE ((tag_aliases.antecedent_name LIKE 's%' ESCAPE E'\\'))
    AND ((tags.name NOT LIKE 's%' ESCAPE E'\\'))
    ORDER BY post_count desc LIMIT 20
  )
) AS unioned_query
ORDER BY post_count desc LIMIT 10

Explain:

Limit  (cost=242.58..242.65 rows=10 width=65)
  ->  Unique  (cost=242.58..242.88 rows=40 width=65)
        ->  Sort  (cost=242.58..242.68 rows=40 width=65)
              Sort Key: public.tags.post_count, public.tags.name
              ->  Result  (cost=0.00..241.51 rows=40 width=65)
                    ->  Append  (cost=0.00..241.51 rows=40 width=65)
                          ->  Limit  (cost=0.00..34.74 rows=20 width=19)
                                ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..31972.63 rows=18406 width=19)
                                      Index Cond: (post_count > 0)
                                      Filter: (name ~~ 's%'::text)
                          ->  Limit  (cost=0.00..206.37 rows=20 width=46)
                                ->  Nested Loop  (cost=0.00..8089.69 rows=784 width=46)
                                      ->  Index Scan Backward using index_tag_aliases_on_post_count on tag_aliases  (cost=0.00..1298.65 rows=882 width=31)
                                            Filter: (antecedent_name ~~ 's%'::text)
                                      ->  Index Scan using index_tags_on_name on tags  (cost=0.00..7.69 rows=1 width=15)
                                            Index Cond: (name = (tag_aliases.consequent_name)::text)
                                            Filter: (name !~~ 's%'::text)

Toks said:

While we're here I'll point out that obscure searches like [% perform well even with the queries that include aliases.

Yeah, that's exactly because they are obscure. Tag aliases still scans entire index, but there's almost nothing to join from tags, so it's cheap.

Anyway, yes, that seems fast enough. There are still certain cases when it's slow (obscure and non-left-anchored queries, like inputing "*[" without quotes into the tag field, which will result into %[%), but those are extremely rare, and, to be frank, cost of 4k is not all that awful. Gonna revive the issue.

Also, a couple of things about the last query: distinct isn't really necessary (uniqueness already ensured by tags.name NOT LIKE 's%'), but it's cheap enough on 40 rows; consequent_name is unnecesary; in the second half of union query it would work better with "SELECT tags.name, tags.post_count <...> and tags.post_count > 0 <...> order by tag_aliases.post_count" - this will take care of delayed post_count update in tag_aliases.

Type-kun said:

Also, a couple of things about the last query: distinct isn't really necessary (uniqueness already ensured by tags.name NOT LIKE 's%'), but it's cheap enough on 40 rows;

tags.name NOT LIKE 's%' only makes sure that if there's a result in the main tags table then duplcates from the tag_aliases table will be filtered out. But within the tag_aliases table it's possible for there to be duplicates. For example, if you take out the distinct then s% returns:

solo, short_hair, smile, thighhighs, thighhighs, skirt, underwear, school_uniform, sitting, tail

Since both stocking and stockings are aliased to thighhighs.

But if this is acceptable I can remove the distinct since it will increase performance a decent amount:

Show

Query:

SELECT * FROM
(
  (
    SELECT tags.name, tags.post_count, tags.category, null AS antecedent_name, null AS consequent_name FROM "tags"
    WHERE (true) AND (name LIKE 's%' ESCAPE E'\\')
    AND (post_count > 0)
    ORDER BY post_count desc LIMIT 20
  )
  UNION ALL
  (
    SELECT tags.name, tag_aliases.post_count, tags.category, tag_aliases.antecedent_name, tag_aliases.consequent_name FROM "tag_aliases"
    INNER JOIN tags ON tags.name = tag_aliases.consequent_name
    WHERE ((tag_aliases.antecedent_name LIKE 's%' ESCAPE E'\\'))
    AND ((tags.name NOT LIKE 's%' ESCAPE E'\\'))
    ORDER BY post_count desc LIMIT 20
  )
) AS unioned_query
ORDER BY post_count desc LIMIT 10

Explain:

Limit  (cost=0.01..62.23 rows=10 width=65)
  ->  Result  (cost=0.01..248.90 rows=40 width=65)
        ->  Merge Append  (cost=0.01..248.90 rows=40 width=65)
              Sort Key: public.tags.post_count
              ->  Limit  (cost=0.00..34.78 rows=20 width=19)
                    ->  Index Scan Backward using index_tags_on_post_count on tags  (cost=0.00..32004.63 rows=18406 width=19)
                          Index Cond: (post_count > 0)
                          Filter: (name ~~ 's%'::text)
              ->  Limit  (cost=0.00..213.22 rows=20 width=46)
                    ->  Nested Loop  (cost=0.00..8358.15 rows=784 width=46)
                          ->  Index Scan Backward using index_tag_aliases_on_post_count on tag_aliases  (cost=0.00..1567.10 rows=882 width=31)
                                Filter: (antecedent_name ~~ 's%'::text)
                          ->  Index Scan using index_tags_on_name on tags  (cost=0.00..7.69 rows=1 width=15)
                                Index Cond: (name = (tag_aliases.consequent_name)::text)
                                Filter: (name !~~ 's%'::text)

Thoughts?

Type-kun said:

in the second half of union query it would work better with "SELECT tags.name, tags.post_count <...> and tags.post_count > 0 <...> order by tag_aliases.post_count" - this will take care of delayed post_count update in tag_aliases.

Adding a >0 condition on tags.post_count has a bad effect on performance. I assume you meant the cached tag_aliases.post_count, I'll add a >0 condition on that.

Toks said:

Adding a >0 condition on tags.post_count has a bad effect on performance. I assume you meant the cached tag_aliases.post_count, I'll add a >0 condition on that.

Huh, it affects performance? What the hell, it shouldn't affect anything; it simply adds another filter on joined table, like (tags.name NOT LIKE 's%' ESCAPE E'\\')... tag_aliases.post_count works, except cases when there's a new tag added along with alias, and a job didn't synchronize counts yet; it's better to not add it, I guess. Out of curiosity, could you post explain for query with tags.post_count > 0? Also note the other changes: order by on tag_aliases.post_count specifically, and selecting actual tags.count instead of synchronized.

Toks said:

Thoughts?

Hmm, that depends. Are there any very different aliases, but starting with same letter, and referring to the same tag? Unable to analyze that using web interface only. If your DB is actual enough, something like this query could shed some light:

select count(*) cnt, tag_aliases.consequent_name, array_agg(tag_aliases.antecedent_name)
from tag_aliases
group by tag_aliases.consequent_name, substr(tag_aliases.antecedent_name from 1 for 1)
having count(*) > 1
order by tag_aliases.consequent_name, cnt desc

Type-kun said:

Hmm, that depends. Are there any very different aliases, but starting with same letter, and referring to the same tag? Unable to analyze that using web interface only. If your DB is actual enough, something like this query could shed some light:

select count(*) cnt, tag_aliases.consequent_name, array_agg(tag_aliases.antecedent_name)
from tag_aliases
group by tag_aliases.consequent_name, substr(tag_aliases.antecedent_name from 1 for 1)
having count(*) > 1
order by tag_aliases.consequent_name, cnt desc
Huge list

cnt consequent_name array_agg
2 !! {!!!,!!!!}
3 .hack//tasogare_no_udewa_densetsu {.hack//legend_of_the_twilight_bracelet,.hack//legend_of_the_twilight,.hack//dusk}
2 /\/\/\ {/\\/\\","/\\"}"
2 +_+ {starry_eyes,star_eyes}
2 2girls {2girl,2_girls}
3 6+boys {6boys,6boy,6+boy}
2 6+girls {6girls,6girl}
3 a1 {initial-g,initial_g,initialg}
2 ad {advertisement,advertising}
3 adjusting_legwear {adjusting_thighhigh,adjusting_pantyhose,adjusting_thighhighs}
2 airplane {planes,plane}
2 akane-iro_ni_somaru_saka {akaneiro_ni_somarusaka,akaneiro_ni_somaru_saka}
2 akino_hamo {hamo_(anarc),hamo_(an-arc)}
2 albert_w_wily {dr._wily,dr_wily}
2 alternate_color {/acol,/ac}
2 alternate_color {alternative_color,alternate_colors}
2 alternate_color_school_swimsuit {green_school_swimsuit,grey_school_swimsuit}
2 alternate_costume {alternative_costume,alternate_outfit}
2 alternate_hair_color {alternative_hair_color,alternate_haircolor}
3 alternate_hairstyle {alternate_hair_style,alternative_hair_style,alternative_hairstyle}
3 alternate_headwear {alternative_headwear,alternative_hat,alternate_hat}
2 amazon_(company) {amazon_(copyright),amazon.com}
2 amidakuji {ghost_leg_lottery,ghost_leg}
2 anal_fingering {fingering_ass,fingering_asshole}
2 angel {angels,archangel}
2 anilingus {annilingus,analingus}
3 anklet {ankle_bracelets,ankle_bracelet,anklets}
2 ano_hi_mita_hana_no_namae_wo_bokutachi_wa_mada_shiranai. {anohana,ano_hi_mita_hana_no_namae_wo_bokutachi_wa_mada_shiranai}
3 anti-materiel_rifle {anti-material_rifle,anti_materiel_rifle,anti_material_rifle}
3 anti-tank_grenade {anti-tank_greandes,anti_tank_grenades,anti_tank_grenade}
3 anti-tank_mine {anti_tank_mine,anti-tank_mines,anti_tank_mines}
2 anus {ass_hole,asshole}
2 apocalypse {apocalyptic,apocalypse_(event)}
2 aqua_eyes {turquoise_eyes,teal_eyes}
2 aqua_hair {turquoise_hair,teal_hair}
2 ar18_(upotte!!) {18_(upotte),18_(upotte!!)}
2 ar18_(upotte!!) {ichihachi_(upotte!!),ichihachi_(upotte)}
3 araragi_(pokemon) {professor_juniper,prof_juniper,prof._juniper}
2 areolae {areolas,areola}
2 arf {alph,aruf}
2 argyle_background {/argylebg,/argbg}
2 armband {arm_band,armbands}
2 armlet {arm_bracelets,armlets}
3 arms_up {arms_raised,arms_above,arms_above_head}
2 asagiri_asagi {asagi_(nippon_ichi),asagi_(makai_kingdom)}
2 asakura_masatoki {asakura_g+,asakura_garo}
2 asobi_ni_iku_yo! {asobi_ni_ikuyo,asobi_ni_ikuyo!}
3 ass {buttocks,butt_cheeks,butt}
2 ass_biting {ass_bite,assbiting}
2 asuka_120_percent {asuka_120,asuka_120%}
2 asuna_(pokemon) {flannery,flannery_(pokemon)}
2 asura_cryin' {asura_crying,asura_cryin}
2 avril_(shukufuku_no_campanella) {avril_(shukufuku),avril_(campanella)}
3 axis_powers_hetalia {hetaria,hetalia,hetalia_axis_powers}
2 ayagi_daifuku {daifuku_(clan),daihuku_(pixiv106903)}
2 ayakashi_(monkeypanch) {ayakashi_(pixiv),ayakashi_(monkeypunch)}
2 azumanga_daiou {azumanga_daioh,azumanga}
4 baka_to_test_to_shoukanjuu {baka_to_tesuto_to_shoukanjuu,bakatest,baka_to_tesuto_to_syokanju,baka_and_test_summon_the_beasts}
3 bandaid {band-aid,bandaids,band_aids}
3 bandaids_on_nipples {bandaid_on_nipples,bandaid_on_nipple,bandaids_on_nipple}
3 baraggan_louisenbairn {barragan_luisenbarn,baraggan,barragan}
2 bare_shoulders {bare_shoulder,bareshoulders}
3 barefoot {barefeet,bare_feet,bare_foot}
3 barrett_m82 {m82,m-82a,m82a1}
2 bear_panties {kumapantsu,kuma_pantsu}
3 bed_sheet {bedsheet,bedsheets,bed_sheets}
2 bed_sheet {sheet,sheets}
2 bel_(pokemon) {bell_(pokemon),bianca_(pokemon)}
4 ben-tou {ben_to,ben_too,ben-to,ben-too}
3 bent_over {bent-over,bending_over,bend_over}
2 beowulf_cadmus {beowulf_kadmas,beowulf_kadmus}
2 bike_shorts {spats,spandex_shorts}
2 bikesuit {bike_suit,biker_suit}
2 bishounen {bishounens,bishonen}
2 biting_testicles {ball_biting,ball_bite}
2 black_hair {blackhair,black-hair}
5 black_legwear {black_thighhighs,black_leggings,black_socks,black_kneehighs,black_pantyhose}
2 black_rock_shooter {blackrock_shooter,black★rock_shooter}
2 blade_(galaxist) {blade_(lovewn),blade_(artist)}
2 bladeless_fan {dyson,dyson_fan}
2 blame_gakuen! {blame_academy!,blame_academy}
2 blank_speech_bubble {blank_word_balloon,blank_word_bubble}
2 blank_speech_bubble {empty_speech_bubble,empty_word_bubble}
4 blonde_hair {blond_hair,blondehair,blonde,blond}
2 blood_stain {bloodstains,blood_stains}
2 bloody_clothes {blood-stained_clothes,blood_on_clothes}
5 blue_legwear {blue_pantyhose,blue_leggings,blue_socks,blue_thighhighs,blue_kneehighs}
2 blue_screen_of_death {bluescreen,bsod}
2 blues_(rockman) {protoman,proto_man}
2 boku_wa_tomodachi_ga_sukunai {/haganai,/bokutomo}
2 bookshelf {bookshelves,bookcase}
2 bottle_fairy {bottle_fairies,bottlefairies}
2 bound_wrists {tied_hands,tied_wrists}
3 bounen_no_xam'd {bounen_no_xamd,bonen_no_xamdou,bounen_no_xamdou}
2 bravely_default:_flying_fairy {bravely_default,bravely_default_flying_fairy}
2 breast_feeding {breastfeeding,breast_feed}
3 breast_grab {boob_grab,breasts_grab,breast_grap}
5 breast_padding {bra_stuffing,breast_pads,breast_stuffing,bra_padding,breast_pad}
2 breast_squeeze {breastsqueeze,breasts_squeeze}
2 breast_sucking {nipple_suck,nipple_sucking}
3 breasts {breats,boobs,breast}
3 brown_hair {brownhair,brown-hair,brunette}
5 brown_legwear {brown_socks,brown_leggings,brown_kneehighs,brown_thighhighs,brown_pantyhose}
2 bruise {bruises,bruised}
2 bukkake {bukake,bukakke}
2 bukkake {cum_everywhere,cum_covered}
2 bull {ox,oxen}
2 bunny {rabbits,rabbit}
2 bunny_ears {rabbit_ears,rabbit_ear}
2 bunny_ears {usagimimi,usamimi}
2 bunnysuit {bunnygirl,bunny_suit}
2 burning_eyes {fiery_eyes,flaming_eyes}
3 burning_hand {flaming_hand,fiery_hand,fire_fist}
2 bust_chart {breast_comparison,breast_chart}
2 bust_cup {breast_cup,breasts_cup}
3 c_(control) {c_the_money_of_soul_and_possibility_control,c:_the_money_of_soul_and_possibility,control:_the_money_of_soul_and_possibility}
3 cable {cord,cables,cords}
2 calne_ca {karune_ca,karune_cl}
2 cardcaptor_sakura {card_captor_sakura,ccs}
2 castlevania_i {super_castlevania_4,super_castlevania_iv}
2 castlevania_iii:_dracula's_curse {castlevania_3,castlevania_iii}
2 celebi_ryousangata {serebii_ryousangata_(pixiv25994),serebi_ryousangata}
2 celestia_ludenberck {celestia_rudenberk,celestia_ludenberg}
2 censored {censoring,censor}
2 cha_(mika) {macchaaji,machaaji}
2 chain-link_fence {chain_link_fence,chainlink_fence}
2 chameleon_(ryokucha_combo) {kamereon,kamere}
3 checkered_background {/ckbg,/checkeredbg,/checkbg}
2 cheek_pinching {pinching_cheek,pinching_cheeks}
2 cheering {cheered,cheer}
2 cherry_blossoms {cherry_tree,cherry_blossom}
3 china_dress {cheongsam,chinese_dress,chinadress}
2 chocolate_banana {choco_banana,chocobanana}
2 chou_tengen_toppa_gurren-lagann {super_tengen_toppa_gurren-lagann,super_tengen_toppa_gurren_lagann}
2 chrono_harlaown {chrono_haraoun,chrono_hallaoun}
2 chun-li {chun_li,chunli}
2 church {chapel,cathedral}
2 chuunibyou_demo_koi_ga_shitai! {chuunibyou_demo_koi_ga_shitai,chuu2koi}
4 cigarette {cigarete,cigarettes,cigarrette,cigarrete}
2 cis_(carcharias) {carcharias!,cercis}
2 clenched_teeth {gritting_teeth,gritted_teeth}
2 clitoris_slip {clit_slip,clitslip}
2 close-up {closeup,close_up}
2 clothed_female_nude_female {clothed_female_naked_female,cfnf}
2 clothed_female_nude_male {/nmcf,/cfnm}
2 clothed_female_nude_male {cfnm,clothed_female_naked_male}
2 clothed_male_nude_female {/nfcm,/cmnf}
2 clothed_male_nude_female {cmnf,clothed_male_naked_female}
2 clothed_male_nude_male {clothed_male_naked_male,cmnm}
4 clothes_pin {clothespin,clothes_pins,clothing_pin,clothespins}
2 cockroach {roach,roaches}
3 collarbone {clavicle,clavicles,collarbones}
2 condensation_trail {contrail,contrails}
2 condensation_trail {vapor_trails,vapor_trail}
2 constricted_pupils {shrunk_pupils,shrunk_eyes}
2 construct_8 {worker-8,worker_8}
2 cooking_idol_ai!_mai!_main! {cooking_idol_ai!_mai!_main,cooking_idol_ai_mai_main}
2 copyright_name {title_drop,title_name}
2 couch {sofa,settee}
3 covering_breasts {breast_cover,breast_covering,breasts_covering}
3 cross-section {crosssection,cross_section,crossection}
2 crossdressing {crossplay,crossdress}
2 crossed_arms {arms_crossed,arms_folded}
3 cube_x_cursed_x_curious {c3,c3:_cube_x_cursed_x_curious,c_cube}
3 cuff_links {cuff_link,cuff-links,cuff-link}
2 cum {semen,sperm}
2 cum_on_breasts {cum_on_tits,cum_between_breasts}
13 cum_on_clothes {cum_on_hat,cum_on_swimsuit,cum_on_pantyhose,cum_under_clothes,cum_on_panties,cum_inside_thighhigh,cum_on_buruma,cum_inside_clothes,cum_on_thighhighs,cum_on_socks,cum_on_clothing,cum_on_shoes,cum_on_stockings}
7 cum_on_lower_body {cum_on_thigh,cum_on_hips,cum_on_leg,cum_on_legs,cum_on_feet,cum_on_thighs,cum_on_foot}
11 cum_on_upper_body {cum_in_armpit,cum_on_hands,cum_on_chest,cum_on_hand,cum_on_back,cum_on_armpits,cum_on_belly,cum_on_ear,cum_on_armpit,cum_on_arm,cum_on_arms}
2 cum_string {cumstring,cum_trail}
3 cunnilingus {cunilingus,cunnillingus,cunillingus}
2 curtsey {curtsie,curtsy}
2 cute_&_girly_(idolmaster) {cute_and_girly_(idolmaster),cute_&_girly(idolmaster)}
2 daisy {daisy_(flower),daisies}
2 dance_pad {dance_mat,dance_platform}
2 danganronpa {dangan_ronpa,dangan-ronpa}
3 daphne_zhang {tanchantanko,tanko_(artist),tandolcedeco_(artist)}
2 dead_or_alive {doa,doax}
2 demon_girl {demon_girls,demongirl}
2 dengeki!_pikachu {pokemon_the_electric_tale_of_pikachu,pokemon:_the_electric_tale_of_pikachu}
2 denim_shorts {daisy_dukes,daisydukes}
4 dew_drop {dewdrop,dew_drops,dew,dewdrops}
2 di_gi_charat {digi_charat,digicharat}
4 dissidia_012_final_fantasy {dissidia_012_[duodecim]_final_fantasy,dissidia_duodecim_final_fantasy,dissidia_012[duodecim]_final_fantasy,dissidia_012}
3 dna^2 {d・n・a2,dna2,dna2}
3 dog_tags {dog_tag,dogtags,dogtag}
3 dokidoki!_precure {doki_doki!_precure,doki_doki_precure,dokidoki_precure}
2 double_bun {twin_bun,twin_buns}
2 double_penetration {dp,doublepenetration}
3 doughnut {doughnuts,donuts,donut}
2 doujima_ryoutarou {dojima_ryotaro,doujima_ryotaro}
2 dragon_quest_viii {dragon_quest_8,dq8}
2 drill_hair {doriru,drillhair}
2 dual_wielding {double_wield,dual_wield}
3 durarara!! {drrr,durarara,drrr!!}
2 dwarf {dwarfs,dwarves}
2 ear_piercing {pierced_ears,pierced_ear}
2 earmuffs {earmuff,ear_muffs}
3 earrings {ear_ring,earring,ear_rings}
2 edomae_lunar {edomae_runa,edomae_luna}
2 electric_socket {electrical_socket,electrical_outlet}
2 electric_socket {power_socket,power_outlet}
3 elemental_gelade {elemental_gerad,erementar_gerad,erementargerad}
2 elf {elf_ears,elven_ears}
3 emanuella_porlallora {emanuela_porelora,emi_(henneko),emanuela_pollarola}
4 embarrassed {embarassed,embarrassing,embarrassment,embarrased}
4 energy_tank {e_tank,e_can,e-can,e-tank}
3 erect_nipples {erect_nipplees,erect_nipple,errect_nipples}
2 eruruw {eruru,eruruu}
2 eureka_seven {koukyoushihen_eureka_seven,koukyoushihen_eureka_7}
3 eureka_seven_ao {eureka_7_astral_ocean,eureka_7_ao,eureka_seven_astral_ocean}
2 ex-keine {exkeine,ex_keine}
2 ex-rumia {ex_rumia,exrumia}
2 extra_breasts {multiple_breasts,multibreast}
3 eyecatch {endcard,eye_catch,end_card}
3 facial_mark {facial_markings,facial_marking,facial_marks}
2 facial_tattoo {face_tattoo,facial_tattoos}
2 fatal_fury {garou_densetsu,garou}
2 fate_testarossa {fate_t_harlaown,fate_testarossa_harlaown}
2 fellatio {blowjob,blow_job}
2 fiery_background {/firebg,/fierybg}
2 fig_leaf {figleaf,figleaves}
2 final_fantasy_iv {finalfantasyiv,ff4}
2 final_fantasy_iv_the_after {/ff4tay,/ff4ta}
2 final_fantasy_tactics {fft,fftactics}
2 final_fantasy_tactics_a2 {final_fantasy_tactics_advance_2,ffta2}
4 final_fantasy_type-0 {final_fantasy_reishiki,final_fantasy_type_zero,final_fantasy_type_0,final_fantasy_agito_xiii}
3 final_fantasy_vii {final_fantasy_7,ff7,ffvii}
4 final_fantasy_x {ff10,ffx,finalfantasy10,final_fantasy_10}
3 final_fantasy_xi {ff11,final_fantasy_11,ffxi}
2 final_fantasy_xii {ff12,ffxii}
2 final_fantasy_xv {ff15,final_fantasy_versus_xiii}
3 finger_in_mouth {finger_inside_mouth,fingers_inside_mouth,fingers_in_mouth}
2 finger_licking {licking_fingers,licking_finger}
3 finger_to_mouth {finger_on_lips,finger_on_mouth,finger_to_lips}
3 fire_emblem:_akatsuki_no_megami {fire_emblem_akatsuki_no_megami,fire_emblem_radiant_dawn,fe10}
3 fire_emblem:_fuuin_no_tsurugi {fire_emblem_sword_of_seals,fe6,fire_emblem_fuuin_no_tsurugi}
3 fire_emblem:_monshou_no_nazo {fire_emblem_monshou_no_nazo,fe3,fire_emblem_mystery_of_the_emblem}
3 fire_emblem:_rekka_no_ken {fire_emblem_rekka_no_ken,fire_emblem_blazing_sword,fe7}
3 fire_emblem:_seima_no_kouseki {fe8,fire_emblem_sacred_stones,fire_emblem_seima_no_kouseki}
3 fire_emblem:_seisen_no_keifu {fire_emblem_genealogy_of_the_holy_war,fire_emblem_seisen_no_keifu,fe4}
3 fire_emblem:_souen_no_kiseki {fire_emblem_souen_no_kiseki,fe9,fire_emblem_path_of_radiance}
2 fire_emblem:_thracia_776 {fire_emblem_thracia_776,fe5}
3 fireball {fireball_(fire),fireballs,fire_ball}
2 fireman's_carry {firemans_carry,fireman_carry}
3 first_aid_kit {medikit,medical_kit,medkit}
3 fish_bone {fishbone,fishbones,fish_bones}
2 fishnet_legwear {fishnet_thighhighs,fishnet_stockings}
2 flat_chest {flatchest,flat_chested}
2 flat_chest {tsurupeta,titty_buds}
2 flcl {furi_kuri,fooly_cooly}
2 flip-flops {flip_flops,flipflops}
2 flit_asuno {fritto_asuno,frite_asuno}
2 floral_print {flower_print,floral_pattern}
2 fn_fal_(upotte!!) {faru_(upotte),faru_(upotte!!)}
4 fnc_(upotte!!) {funko_(upotte),funco_(upotte!!),funco_(upotte),funko_(upotte!!)}
2 forehead_kiss {kiss_on_forehead,kissing_forehead}
2 forte_(rockman) {bass_(megaman),bass_(mega_man)}
3 fresh_precure! {fresh_pretty_cure,fresh_pretty_cure!,fresh_precure}
3 frilled_legwear {frilled_socks,frilled_kneehighs,frilled_thighhighs}
2 frills {frilly,frill}
2 frog_costume {frogsuit,frog_suit}
2 fujiwara_no_mokou {/fm,/fnm}
2 full_metal_panic! {full_metal_panic,fullmetalpanic}
2 full_moon_wo_sagashite {fmos,full_moon_o_sagashite}
2 fullmetal_alchemist {fma,full_metal_alchemist}
2 futa_with_female {futa_on_female,female_on_futa}
2 futaori_arisa {yuuki_(momokanku),yuuki_(pixiv134222)}
2 futari_wa_precure {futari_wa_precure_(1st),futari_wa_pretty_cure}
2 g3a3_(upotte!!) {jiisuri_(upotte!!),jiisuri_(upotte)}
2 gakuen_utopia_manabi_straight! {manabi_straight!,manabi_straight}
2 galaxy_angel_rune {galaxy_angelune,galaxy_angel_ii}
2 galil_ar_(upotte!!) {galil_(upotte),galil_(upotte!!)}
5 gangbang {gang_sex,gangsex,gang_bang,gang_rape,gangrape}
2 garnet_(shukufuku_no_campanella) {garnet_(campanella),garnet_(shukufuku)}
2 gears {cog,cogs}
3 gem {gemstones,gems,gemstone}
2 gem {jewel,jewels}
2 gem {precious_stone,precious_stones}
3 getsumento_heiki_miina {getsumen_to_heiki_mina,getsumento_heiki_mina,getsumen_to_heiki_miina}
2 gift {present,presents}
2 ginga_eiyuu_densetsu {legend_of_the_galactic_heroes,logh}
2 giru_(dragon_ball) {giru_(dragonball_gt),giru_(dragon_ball_gt)}
3 glasses {meganekko,meganeko,megane}
2 go!go!_maniac {go!_go!_maniac,go_go_maniac}
2 gokou_tamaki {gokou_ruri's_little_sister,gokou_ruri's_youngest_sister}
4 gold_bar {gold_ingot,gold_brick,gold_bullion,gold_bars}
2 golem_(shukufuku_no_campanella) {golem_(shukufuku),golem_(campanella)}
2 gonoike_biwa {biwa_(kt),biwa_(pixiv_267543)}
2 goo_girl {slime_girl,slimegirl}
2 gothic_lolita {gothloli,gosurori}
2 goto_p {goto-p,gotop}
2 gradient_background {/gradientbg,/gbg}
5 gradient_legwear {gradient_socks,gradient_leggings,gradient_pantyhose,gradient_thighhighs,gradient_kneehighs}
2 graphite_(medium) {pencil_sketch,pencil_(medium)}
2 green_eyes {greeneyes,green-eyes}
5 green_legwear {green_kneehighs,green_socks,green_leggings,green_thighhighs,green_pantyhose}
3 greville_de_blois {grevil_de_broix,greville_de_broix,grevil_de_blois}
2 grey_background {/greybg,/graybg}
11 grey_legwear {gray_kneehighs,grey_leggings,gray_pantyhose,gray_leggings,gray_socks,grey_socks,grey_thighhighs,gray_thighhighs,gray_legwear,grey_kneehighs,grey_pantyhose}
2 greyscale {black_and_white,b&w}
4 grimmjow_jaegerjaquez {grimmjow_jeagerjaques,grimmjow_jaggerjack,grimmjow,grimmjow_jaegerjaques}
2 groping {fondling,fondle}
2 group_sex {fivesome,foursome}
2 gundou_musashi {gun_musashi,gundoh_musashi}
2 gunxsword {gunsword,gun_sword}
4 gyakuten_saiban {ace_atourney,ace_attorney,ace_attourney,ace_atorney}
2 gym_storeroom {gym_equipment_shed,gym_storage_room}
3 hair_bell {hair_bells,hairbell,hairbells}
2 hair_bow {hair_bows,hairbow}
2 hair_dryer {blowdryer,blow_dryer}
2 hair_flower {hairflower,hair_flowers}
4 hair_ornament {hair_ornaments,hair_decs,hair_accessories,hair_accessory}
2 hair_ribbon {ribbon_in_hair,ribbons_in_hair}
3 hair_rings {hair_loop,hair_loops,hair_ring}
2 hair_tie {hair_ties,hairtie}
3 hairclip {hair_clip,hairclips,hair_clips}
2 hairlocs {hair_locs,hair_loc}
2 hairpin {hair_pin,hairpins}
2 hajimete_no_koi_ga_owaru_toki_(vocaloid) {when_the_first_love_ends_(vocaloid),when_the_first_love_ends}
2 halftone_background {/halftonebg,/htbg}
2 hanako_(pokemon) {delia_(pokemon),delia_ketchum}
2 hanako_(pokemon) {mrs_ketchum,mrs._ketchum}
2 hanamaru_youchien {hanamaru_yochien,hanamaru_kindergarten}
2 hanaukyo_maid_tai {hanaukyomaidtai,hanaukyomaids}
2 hand_on_own_chest {hand_to_chest,hand_to_own_chest}
2 hand_puppet {handpuppet,hand_puppets}
3 hand_to_own_mouth {hand_to_mouth,hands_to_mouth,hands_to_own_mouth}
2 hands_on_another's_cheeks {hands_on_cheeks,hands_on_cheek}
2 hands_on_own_cheeks {hands_to_cheeks,hands_to_cheek}
2 hanging_breasts {hanging_boob,hangingboob}
3 hard_drive {harddrive,hard_disc_drive,hard_disk_drive}
2 hard_translated {hard_translation,hardsub}
4 harrier_jump_jet {bae_harrier,bae_sea_harrier_frs.mk.2,bae_sea_harrier_frs.mk.1,bae_sea_harrier}
3 harrier_jump_jet {sea_harrier_frs.mk.1,sea_harrier,sea_harrier_frs.mk.2}
2 harunatsu_akito {haruka_akito,happy_flame_time}
2 hatsune_miku_(roshin_yuukai/nitamagomix) {hatsune_miku_(roshin_yukai/nitamagomix),hatsune_miku_(meltdown/nitamagomix)}
3 hayate_no_gotoku! {hayate_no_gotoku!!,hayate_the_combat_butler,hayate_no_gotoku}
3 heads-up_display {heads-up-display,heads_up_display,hud}
3 heartcatch_precure! {heartcatch_precure,heartcatch_pretty_cure!,heartcatch_pretty_cure}
2 heero_yuy {heero_yui,hiiro_yui}
2 hentai_ouji_to_warawanai_neko. {henneko,hentai_ouji_to_warawanai_neko}
2 high_heels {heels,highheels}
2 highres {high_res,hires}
2 hip_bones {pelvic_bone,pelvic_bones}
2 hiroshima_touyou_carp {hiroshima_toyo_carp,hiroshima_carp}
2 hitodama {soul_flame,spirit_flame}
3 holding_fruit {holding_strawberry,holding_apple,holding_peach}
2 holding_hands {hand_holding,handholding}
2 holographic_monitor {holographic_screen,holographic_display}
2 honda_hiroto {tristan_taylor,tristan_timothy_taylor}
2 hoshino_madoka {aya_(pixiv441971),aya_ojo}
3 huge_breasts {huge_boobs,huge_breast,huge_tits}
2 huge_weapon {huge_sword,huge_gun}
5 hyakka_ryouran_samurai_girls {hyakka-ryouran,hyakka_ryouran,hyakka_ryoran_samurai_girls,hyakka-ryoran,hyakka_ryoran}
2 ian_chase {deliciousorange,delicious_orange}
5 ice_cream {icecreams,ice-creams,icecream,ice-cream,ice_creams}
5 ice_cream_cone {icecream_cone,ice_cream_cones,icecream_cones,ice-cream_cone,ice-cream_cones}
2 ichigo_100_percent {ichigo_100,ichigo_100%}
2 ichiko_oharu {oharu_(koigusuri),oharu_(pixiv85447)}
2 idolmaster {idolm@ster,idol_master}
2 ikari_gendou {ikari_gendoh,ikari_gendo}
2 ikegami_akane {akane_makes_revolution,akane_ikegami}
2 imagining {day_dreaming,daydreaming}
2 inasaki_shirau {shirau_inazaki,shubesuta}
2 infirmary {nurse's_office,nurse_office}
2 injury {injured,injuries}
2 injury {wounded,wounds}
2 inline_skates {rollerblades,roller_blades}
2 insect_girl {buggirl,bug_girl}
2 interlocked_fingers {intertwined_fingers,interlaced_fingers}
2 intravenous_drip {iv_drip,iv}
2 isabella_valentine {ivy_valentine,ivy_(soul_calibur)}
5 ishikei {nise_midi_doronokai,nisemidi,nisemididoronokai,nise,nise_midi_doro_no_kai}
3 jack-o'-lantern {jack-o-lantern,jack_o'_lantern,jack_o_lantern}
3 jelly_bean {jellybean,jelly_beans,jellybeans}
2 jewelry {jewellery,jewelery}
2 jiaozi {gyoza,gyouza}
2 jiji_(majo_no_takkyuubin) {jiji_(character),jiji_(kiki's_delivery_service)}
3 jingle_bell {jingle_bells,jinglebell,jinglebells}
2 jinki {jinkiextend,jinki_extend}
2 jinroku {jinrock,jinrok}
2 jinrui_wa_suitai_shimashita {jintai,jinrui_wa_suitaishimashita}
2 jojo_no_kimyou_na_bouken {/jjba,/jjkb}
2 jounouchi_katsuya {joey_wheeler,joseph_wheeler}
3 jpeg_artifacts {jpegartifacts,jpeg_artefacts,jpg_artifacts}
2 juliet_sleeves {puffy_shoulders_long_sleeves,puffy_shoulder_long_sleeves}
2 jungle_wa_itsumo_hare_nochi_guu {hareguu,hare+guu}
2 junsaa_(pokemon) {jenny_(pokemon),junsa_(pokemon)}
2 juu-ou-sei {jyu_oh_sei,jyu-oh-sei}
5 k-on! {keion,k-on,kon!,keion!,k-on!!}
2 kaburagi_t_kotetsu {kotetsu_t_kaburagi,kaburagi_t._kotetsu}
2 kafu {simple@house,simple_house}
2 kagamine_rin_(roshin_yuukai) {kagamine_rin_(roshin_yukai),kagamine_rin_(meltdown)}
2 kagamine_rin_(roshin_yuukai/hard_rkmix) {kagamine_rin_(meltdown/hard_rkmix),kagamine_rin_(roshin_yukai/hard_rkmix)}
3 kallen_stadtfeld {kouzuki_karen,kallen,kouzuki_kallen}
9 kami-sama_no_memo-chou {kamisama_no_memochou,kamisama_no_memo_chou,kamisama_no_memo-chou,kami_sama_no_memochou,kami-sama_no_memo_chou,kami_sama_no_memo_chou,kami_sama_no_memo-chou,kami-sama_no_memochou,kamimemo}
2 kareshi_kanojo_no_jijou {kare_kano,karekano}
2 kasumi_(pokemon) {misty,misty_(pokemon)}
2 kate_(doubutsu_no_mori) {labelle_able,label_able}
3 kawarajima_kou {koh-kawarajima,koh_kawarajima,kawarajima_koh}
2 kei_(keigarou) {keigarou,kei_(artist)}
2 kei_jiei {momoego,momokan}
2 kfc {kentucky_fried_chicken,kfc_(company)}
3 kikuchi_shun'ya {kikuchi_jun'ya,kikuchi_junya,kikuchi_shunya}
2 killua_zoldyck {killua_zaoldyeck,killua}
2 kin-iro_mosaic {kin'iro_mosaic,kiniro_mosaic}
2 king_of_fighters {kof,kingoffighters}
2 kirijou_mitsuru {mitsuru_kirijou,mitsuru_kirijyo}
3 knee_pads {kneepad,knee_pad,kneepads}
4 kneehighs {knee_highs,kneehigh_socks,knee_socks,kneesocks}
2 kneepits {knee_pit,kneepit}
2 koi_wa_sensou_(vocaloid) {love_is_war_(vocaloid),love_is_war}
2 koko_(konjiki_no_gash!!) {koko_(konjiki_no_gash),koko_(zatch_bell)}
3 kokoro_toshokan {kokorotoshokan,kokorolibrary,kokoro_library}
2 kore_ga_watashi_no_goshujin-sama {he_is_my_master,himm}
2 kore_wa_zombie_desu_ka? {is_this_a_zombie,is_this_a_zombie?}
2 kore_wa_zombie_desu_ka? {kore_wa_zombie_desu_ka,korezom}
2 koutari_yuu {yuu_(black_rock_shooter),yuu_(brs)}
2 kumo_no_mukou_yakusoku_no_basho {beyond_the_clouds,beyond_the_clouds_the_promised_place}
4 kyoukaisenjou_no_horizon {horizon_on_the_borderline,horizon_over_the_middle_of_nowhere,horizon_on_the_middle_of_nowhere,horizon_in_the_middle_of_nowhere}
3 kyoukaisenjou_no_horizon {kyoukaisen-jou_no_horizon,kyoukai_sen-jou_no_horizon,kyoukai_senjou_no_horizon}
2 kyoushoku_soukou_guyver {bio-booster_armour_guyver,bio-booster_armor_guyver}
2 kyoushoku_soukou_guyver {the_bioboosted_armour_guyver,the_bioboosted_armor_guyver}
2 kyubey {kyuubee,kyuubey}
2 l85a1_(upotte!!) {eru_(upotte),eru_(upotte!!)}
2 l85a1_(upotte!!) {l_(upotte!!),l_(upotte)}
2 la_pucelle {la_pucelle_tactics,lapucelle}
2 labia_clamps {pussy_clamps,pussy_clamp}
2 lactation {milking,milk_breasts}
3 ladies_versus_butlers! {ladies_x_butlers!,ladies_x_butlers,ladies_versus_butlers}
2 lamia {naga-ette,naga}
6 lamppost {street_lamp,streetlights,streetlight,street_light,streetlamp,street_lights}
2 lamppost {lamp-post,lamp_post}
3 lap_pillow {head_on_lap,head_in_lap,hizamakura}
2 large_areolae {big_areolae,big_areola}
3 large_breasts {large_tits,large_breast,large_boobs}
2 last_exile:_ginyoku_no_fam {last_exile:_fam,_the_silver_wing",last_exile:_fam_the_silver_wing}"
2 left-to-right_manga {left_to_right_manga,left-to-right}
2 leg_lift {leg_raise,leg_raised}
2 lelouch_lamperouge {lelouch,lelouch_vi_britannia}
2 letterboxed {letter_boxed,letterbox}
2 licking {licks,lick}
2 lightning_farron {lightning_(ffxiii),lightning_(ff13)}
2 lily_pad {lilypad,lilypads}
2 lilynette_gingerbuck {lilynette,lilynette_gingerback}
2 lindy_harlaown {lindy_hallaoun,lindy_haraoun}
2 lineup {line-up,line_up}
2 locked_arms {arms_linked,arm_in_arm}
2 lollipop {lolipop,lollipops}
2 look-alike {look_alike,lookalike}
2 lotte_no_omocha! {astarotte_no_omocha,astarotte_no_omocha!}
2 lotte_no_omocha! {lotte's_plaything,lotte_no_omocha}
2 lotte_no_omocha! {rotte_no_omocha,rotte_no_omocha!}
2 love_lab {ren'ai_lab,renai_lab}
2 lowleg_panties {low_leg_panties,low-leg_panties}
3 lying {laying_down,lying_down,laying}
2 m14_(upotte!!) {14_(upotte),14_(upotte!!)}
2 m14_(upotte!!) {ichiyon_(upotte),ichiyon_(upotte!!)}
2 m16a4_(upotte!!) {16_(upotte!!),16_(upotte)}
2 m16a4_(upotte!!) {ichiroku_(upotte),ichiroku_(upotte!!)}
6 machisu_(pokemon) {lt_surge_(pokemon),lt._surge,lt._surge_(pokemon),lieutenant_surge,lt_surge,lieutenant_surge_(pokemon)}
2 macross_frontier:_itsuwari_no_utahime {macross__frontier:_itsuwari_no_utahime,macross_frontier:_the_false_diva}
4 magic_circle {mahoujin,magical_circle,magical_circles,magic_circles}
2 magical_antique {magicalantique,majian}
3 magical_girl {magical_girls,magic_girl,mahou_shoujo}
2 magician's_academy {macademi_wasshoi,macademi_wasshoi!}
2 magister_(bigbakunyuu) {mnll,magister}
2 mahou_shoujo_lyrical_nanoha {mahoushoujolyricalnanoha,mahou_shoujo_lyirical_nanoha}
2 mahou_shoujo_lyrical_nanoha_a's {mahou_shoujo_lyirical_nanoha_a's,mahoushoujolyricalnanohaas}
2 mahou_tsukai_tai! {magic_user's_club,mahou_tsukai_tai}
4 maid {maid_costume,maid_outfit,maids,maid_uniform}
2 maid_headdress {maid_cachusha,maid_headband}
2 maka_albarn {maka_alban,maka_arubaan}
2 maka_albarn_(cosplay) {maka_alban_(cosplay),maka_arubaan_(cosplay)}
2 makai_tenshi_jibril {jiburiru,jibril}
4 makaimura {ghouls_n_ghosts,ghouls_'n_ghosts,ghosts_n_goblins,ghosts_'n_goblins}
2 makeup {make-up,make_up}
3 male {male_only,men,man}
2 mamono_hunter_youko {devil_hunter_youko,devil_hunter_yohko}
2 man_(man-room) {man_(artist),man_(kisidayouiti)}
2 mandarin_orange {mikan,mandarin}
2 manga_(object) {doujin_(object),doujinshi_(object)}
3 mapo_doufu {mapo_tofu,maabou_doufu,mapotofu}
2 maria-sama_ga_miteru {/marimite,/msgm}
2 maria-sama_ga_miteru {maria_watches_over_us,marimite}
3 mars_symbol {male_sign,mars_sign,male_symbol}
2 mars_symbol {iron_sign,iron_symbol}
2 marvel_vs._capcom {marvel_vs_capcom,mvc}
2 marvel_vs._capcom_2 {mvc2,marvel_vs_capcom_2}
2 marvel_vs._capcom_3 {mvc3,marvel_vs_capcom_3}
2 masturbation {masturbating,masturbate}
2 megaphone {bullhorn,bull_horn}
2 melon_bread {meronpan,melonpan}
2 messiah_cage {mystic_cage,messiah(artist)}
2 midori_no_hibi {midorinohibi,midori_days}
2 mikagami_hiyori {strange_chameleon,strangechameleon}
2 mikazuki_akira! {mikazuki_akira,mikaduki_akira}
2 mime_jr. {mime_jr,mime_junior}
3 miniskirt_pirates {mouretsu_pirates,miniskirt_uchuu_kaizoku,mouretsu_uchuu_kaizoku}
2 mitsudomoe {mitsudo_moe,mitsu_domoe}
2 molestation {molester,molesting}
2 momoko_120_percent {momoko_120,momoko_120%}
2 momoman_(pink_voltage) {pink_voltage,peach_man}
3 monochrome {monochorme,monochome,monochromatic}
5 moriya's_iron_rings {moriya's_iron_ring,moriya's_ring,moriyas_iron_rings,moriyas_iron_ring,moriya's_rings}
2 mortarboard {graduation_cap,graduate_cap}
3 moudoku_(decopon3rd) {11_(dekopon3rd),11_(decopon3rd),11_(凸-pon3rd)}
2 mousou_(mousou_temporary) {moso,moso_(mousou_temporary)}
2 mr._mime {mr_mime,mister_mime}
5 multicolored_legwear {multicolored_kneehighs,multicolored_socks,multicolored_leggings,multicolored_pantyhose,multicolored_thighhighs}
2 multiple_persona {quintuple_persona,quadruple_persona}
5 multiple_tails {multiple_tail,multi_tail,multitail,multi_tails,multitails}
2 muscle {muscular,muscles}
2 musen-shiki_sanhankikan {musen_shiki_sanhankikan,musenshiki_sanhankikan}
2 mushihime-sama {mushihime,mushihimesama}
3 musical_note {music_note,musical_notes,music_notes}
2 muten_roushi {master_roshi,muten_roshi}
2 muvluv {muv-luv,muv_luv}
4 my-hime {mai_hime,mai-hime,my_hime,maihime}
6 my-otome {my_zhime,maiotome,my_otome,my-zhime,mai_otome,mai-otome}
3 my-otome_s.ifr {mai_otome_sifr,my-otome_sifr,mai_otome_s.ifr}
2 myu-po {miyuu_hodoh,miyuuhodoh}
2 nail_polish {nailpolish,nail_varnish}
2 naitou_ryuu {nai-tech,naitou_ryu}
2 naked_apron {nude_apron,nakedapron}
2 naked_coat {nude_coat,naked_jacket}
2 naked_ribbon {nude_ribbon,nakedribbon}
3 nanakamado_(pokemon) {prof_rowan,professor_rowan,prof._rowan}
2 narukami_yuu {protagonist_(persona_4),protagonist_(persona4)}
2 navel {belly_button,bellybutton}
2 negitama_(nagi) {hagi__(pixiv101455),hagi_(pixiv101455)}
4 nekoarc {neco-arc,necoarc,neco_arc,neko-arc}
4 nekoarc_chaos {neko_arc_chaos,necoarc_chaos,neco_arc_chaos,neco-arc_chaos}
3 nelliel_tu_odelschwanck {nel_tu,nelliel,neliel_tu_oderschvank}
2 nemunemu_(candy_paddle) {nemunemu_(shuumatsu_shorijou),nemunemu_(syumatsusyorijou)}
2 neru_fia {neru_fuia,neruneru_(artist)}
2 new_year {new_years,newyear}
3 nhk_ni_youkoso! {nhk_ni_youkoso,nhk_ni_yookoso!,nhk_ni_yookoso}
3 nhk_ni_youkoso! {welcome_to_the_nhk,welcome_to_nhk,welcome_to_the_n.h.k.}
2 niconico {nico_nico_douga,nicovideo}
5 nightgown {nightie,night_dress,nighty,night_gown,nightdress}
2 nikuman {meat_bun,meatbun}
2 nikuman {pork_bun,porkbun}
3 nipple_slip {nipslip,nippleslip,nip_slip}
2 nishii_(nitroplus) {ni_theta,niθ}
4 nnoitra_gilga {nnoitra,nnoitora_gilga,nnoitora_jiruga,nnoitra_jiruga}
2 no_hat {hatless,hat-less}
3 no_pants {no_skirt,nopants,noskirt}
2 no_pants {pantless,pantsless}
2 no_pussy {missing_pussy,missing_vagina}
2 no_pussy {novagina,no_vagina}
5 nono_(top_wo_nerae_2!) {nono_(gunbuster_2!),nono_(top_wo_nerae_2),nono_(top_wo_nerae!),nono_(top_wo_nerae),nono_(gunbuster_2)}
2 noses_touching {nose_to_nose,nose_touching}
2 nurse {nurse_uniform,nurse_outfit}
2 o-ring_top {o-ring_bikini_top,o_ring_top}
4 obentou {bento-box,bentou,bento,bento_box}
2 oda_kou {kou_hime,kouhime}
3 odamaki_(pokemon) {prof._birch,prof_birch,professor_birch}
2 odamaki_sapphire {sapphire_birch,sapphire_(pokemon)}
2 off_shoulder {off-shoulder,off_shoulders}
2 office_lady {officelady,ol}
2 ofuro_mantarou {ofuro_(pixiv4010),ofuro_(artist)}
2 one-eyed {one_eyed,one_eye}
2 one-piece_swimsuit {one_piece_swimsuit,one-piece}
2 onigiri {rice_ball,riceball}
3 onsen {hotspring,hot_spring,hot_springs}
2 ookami-san {/otsnn,/ookami-san}
2 ookido_green {green_(pokemon),green_oak}
2 ookido_nanami {daisy_oak,daisy_(pokemon)}
2 ookido_shigeru {gary_oak,gary_(pokemon)}
3 ookido_yukinari {prof._oak,professor_oak,prof_oak}
2 ookiku_furikabutte {big_windup,big_windup!}
2 orange_(satsurikukuma) {orange_(pixiv389641),orange_(saturikukuma)}
5 orange_legwear {orange_socks,orange_thighhighs,orange_kneehighs,orange_pantyhose,orange_leggings}
2 ore_no_imouto_ga_konna_ni_kawaii_wake_ga_nai {ore_no_imouto_ga_konnani_kawaii_wake_ga_nai,oreimo}
2 otakubeam {otsukura_mahiro,otaku_beam}
2 outdoors {outside,outdoor}
2 outstretched_hand {hands_outstretched,hand_outstretched}
2 oven_mitts {oven_mitt,oven_mittens}
2 ozawa_akifumi {orisawa_akifumi,orisawa_akihumi}
2 paizuri {titfuck,tit_fuck}
3 pajamas {pyjamas,pajama,pyjama}
2 pale_skin {pale,paleskin}
3 pani_poni_dash! {pani_poni_dash,paniponidash,pani_poni}
2 pani_poni_dash! {/ppd!,/ppd}
2 pant_suit {pants_suit,pantsuit}
3 panties {pantsu,pantie,panty}
4 panties_under_pantyhose {panties_under_pantiehose,panties_below_pantyhose,panties_underneath_pantyhose,panties_behind_pantyhose}
6 panty_pull {pantsu_pull,panties_down,panty_down,pantsupull,panties_pull,pantypull}
2 pantyhose_pull {pantyhosepull,pantyhose_down}
3 pantyshot {panchira,panty_flash,panty_shot}
2 pantyshot_(sitting) {pantyshot_sitting,panchira_sit}
6 papa_no_iu_koto_wo_kikinasai! {papakiki,papa_no_iukoto_wo_kikinasai!,papa_no_iukoto_o_kikinasai!,papa_no_iu_koto_wo_kikinasai,papa_no_iukoto_wo_kikinasai,papa_no_iukoto_o_kikinasai}
3 papa_no_iu_koto_wo_kikinasai! {listen_to_me_girls._i_am_your_father!,listen_to_me_girls_i_am_your_father!,listen_to_me_girls_i’m_your_father!}
2 partially_translated {partial_translation,partly_translated}
3 paw_print {pawprints,paw_prints,pawprint}
2 peeing_self {peeing_pants,peeing_panties}
2 penis {cocks,cock}
2 penis {dick,dicks}
2 personality_switch {body_switch,body_swap}
3 petenshi_(dr._vermilion) {dr_vermilion,dr.vermilion,dr._vermilion}
2 phonograph {record_player,record_machine}
3 photo_(object) {picture,photograph_(object),pictures}
2 piano {analog_piano,acoustic_piano}
4 pickaxe {pick_axe,pick-axe,pickax,pick-ax}
2 piercing {pierced,piercings}
2 pig {piglet,pigs}
2 pigeon-toed {pigeon_toed,pigeon_toes}
2 pilot_suit {flight_suit,flightsuit}
5 pink_legwear {pink_leggings,pink_thighhighs,pink_socks,pink_pantyhose,pink_kneehighs}
2 pinstripe_pattern {pinstripe,pinstripes}
2 platform_footwear {platform_shoes,platforms}
3 platinum_berlitz {platinum_(pokemon),platina_(pokemon),platina_berlitz}
2 playing_games {gaming,girls_playing_games}
2 playstation_vita {ps_vita,psvita}
2 plugsuit {plug_suit,plugsuits}
2 pointing_up {pointing_to_the_sky,pointing_skyward}
3 pointy_ears {pointed_ears,pointy-ears,pointy_ear}
3 poke_ball {pokeball,pokeballs,poke_balls}
2 pokemon {pokemons,pocket_monsters}
3 pokemon_+_nobunaga_no_yabou {pokemon_plus_nobunaga_no_yabou,pokemon_+_nobunaga's_ambition,pokemon_conquest}
4 pokemon_bw {pokemon_black_and_white,pokemon_black,pokemon_b&w,pokemon_white}
6 pokemon_bw2 {pokemon_b2&w2,pokemon_b&w2,pokemon_black_2,pokemon_white_2,pokemon_black_2_and_white_2,pokemon_b2w2}
7 pokemon_dppt {pokemon_platinum,pokemon_pearl,pokemon_diamond,pokemon_d&p,pokemon_dp,pokemon_dpp,pokemon_diamond_and_pearl}
6 pokemon_frlg {pokemon_lg,pokemon_fr&lg,pokemon_firered_and_leafgreen,pokemon_firered,pokemon_leafgreen,pokemon_fr}
6 pokemon_gsc {pokemon_silver,pokemon_gold,pokemon_g&s,pokemon_gs,pokemon_gold_and_silver,pokemon_crystal}
6 pokemon_hgss {pokemon_hg,pokemon_heartgold,pokemon_soulsilver,pokemon_heartgold_and_soulsilver,pokemon_ss,pokemon_hg&ss}
12 pokemon_rgby {pokemon_rby,pokemon_r&b,pokemon_red_and_blue,pokemon_red,pokemon_green,pokemon_red_and_green,pokemon_blue,pokemon_yellow,pokemon_rb,pokemon_rg,pokemon_r&g,pokemon_rgb}
6 pokemon_rse {pokemon_sapphire,pokemon_ruby,pokemon_ruby_and_sapphire,pokemon_emerald,pokemon_r&s,pokemon_rs}
2 pokemon_special {pokemon_adventures,pocket_monsters_special}
4 pokemon_xd {pokemon_xd_gale_of_darkness,pokemon_xd:_yami_no_kaze_dark_lugia,pokemon_xd_yami_no_kaze_dark_lugia,pokemon_xd:_gale_of_darkness}
4 pokemon_xy {pokemon_x,pokemon_y,pokemon_x&y,pokemon_x_and_y}
2 poleaxe {pole_axe,pollaxe}
2 policeman {police-man,police_man}
2 policewoman {police_woman,police-woman}
2 polka_dot {polka-dot,polka_dots}
2 polka_dot_background {/polkadotbg,/pdbg}
8 pom_poms {pompoms,pompom,pom-pom,pom-poms,pompon,pom-pons,pompons,pom-pon}
2 power-up {power_up,powerup}
3 power_armor {powered_armor,power_armour,powered_armour}
2 powerpuff_girls_z {demashita_powerpuff_girls_z,demashita!_powerpuff_girls_z}
4 print_legwear {print_thighhighs,print_pantyhose,print_kneehighs,print_leggings}
3 pubic_hair {pubes,pubichair,public_hair}
2 puchi_puri_yucie {puchi_puri_yuushi,petite_princess_yucie}
2 purple_hair {purplehair,purple-hair}
5 purple_legwear {purple_kneehighs,purple_leggings,purple_pantyhose,purple_thighhighs,purple_socks}
2 pussy {vagina,vulva}
2 raccoon_ears {tanukimimi,tanuki_ears}
2 railroad_tracks {railway_tracks,railroad}
3 rakudai_ninja_rantarou {nintama_rantaro,nintama,nintama_rantarou}
2 ralph_c_belmondo {trevor_c_belmont,trevor_belmont}
3 ranguage {flench,faux_finnish,faux_greek}
3 ranma_1/2 {ranma?,ranma1/2,ranma_?}
2 rappa_(rappaya) {rapattu,rappa_(pixiv130037)}
2 re_mii {le_mii,lemii}
2 reach-around {reacharound,reach_around}
2 really?_really! {really_really,really?really!}
3 recurring_image {copy-pasting,copy-pasted,copy-paste}
2 red-framed_glasses {red_framed_glasses,red-rimmed_glasses}
2 red_eyes {red_eye,redeyes}
3 red_hair {redhead,red_head,redhair}
5 red_legwear {red_socks,red_kneehighs,red_pantyhose,red_thighhighs,red_leggings}
2 remote_control {remote,remote_controller}
2 renais_cardiff_shishiou {renais_cardiff_shishioh,renais_cardiff_shishio}
2 renkin_san-kyuu_magical_pokaan {majipoka,magipoka}
2 rice_bowl {ricebowl,rice_bowls}
2 rockman {megaman,mega_man}
2 rockman_(character) {mega_man_(character),megaman_(character)}
2 rockman_x {mega_man_x,megaman_x}
2 rolling_eyes {rolleyes,rolled_eyes}
2 roman_numerals {roman_numbers,roman_number}
2 romeo_to_cinderella_(vocaloid) {romeo_and_cinderella,romeo_and_cinderella_(vocaloid)}
2 rozen_maiden {rosen_maiden,rozenmaiden}
2 rubber_duck {rubber_ducky,rubber_duckie}
2 ryouko_(tenchi_muyou!) {hakubi_ryoko,hakubi_ryouko}
2 ryouko_(tenchi_muyou!) {ryouko_(tenchi_muyou),ryoko_(tenchi_muyo)}
2 saigyouji_yuyuko's_fan_design {charisma_fan,charismatic_fan}
2 saigyouji_yuyuko's_fan_design {yuyuko's_fan_design,yuyuko's_fan_pattern}
2 sailor {sailor_suit,sailor_uniform}
3 sajou_manaka {sajyou_aika,sajou_aika,sajyou_manaka}
2 sakigake!!_cromartie_koukou {cromartie,cromartie_high_school}
2 sako_rk_95_(upotte!!) {sako_(upotte!!),sako_(upotte)}
2 sakura_taisen {sakura_wars,sakurataisen}
2 sakuya_(eureka_seven) {sakuya_(eureka_7),sakuya_(e7)}
2 samurai_spirits {samurai_shodown,samuraispirits}
3 santa_costume {santa_outfit,santa,santa_suit}
2 sarah_(ff1) {princess_sarah_(ff1),princess_sara_(ff1)}
2 sarashi {bandage_bra,bandagebra}
2 satoshi_(pokemon) {ash_ketchum,ash_(pokemon)}
2 satou_atsuki {as-special,as_special}
6 scan_artifacts {scan_artefact,scanning_artifacts,scanningartifacts,scan_artefacts,scanner_artifacts,scan_artifact}
2 scan_artifacts {badscan,bad_scan}
2 school_rumble {sukuran,schoolrumble}
3 school_swimsuit {sukumizu,sukimizu,school_swimsuits}
4 school_uniform {schoolgirl,school_girl,school_uniforms,seifuku}
3 science_fiction {sci-fi,scifi,sci_fi}
2 see-through {seethrough,see_through}
2 seikai_no_senki {seikainosenki,sekainosenki}
2 seiken_densetsu_3 {seikendensetsu3,sd3}
2 seiyuu {voice_actor,voice_actress}
2 semi-rimless_glasses {half-rim_glasses,half_rim_glasses}
2 seong_mi-na {seung_mina,seung_mi-na}
2 sex {fuck,fucking}
2 sf-a2_miki {miki,miki_(vocaloid)}
4 sg550_(upotte!!) {sig_(upotte),shigu_(upotte),sig_(upotte!!),shigu_(upotte!!)}
2 sharp_teeth {pointed_teeth,pointy_teeth}
2 shaved_ice {kakigoori,kakigori}
4 sheet_music {music_sheet,music_sheets,musical_sheets,musical_sheet}
2 shell_bikini {shell_bra,seashell_bikini}
2 shibari {ropebondage,rope_bondage}
2 shichimenchou {shitimentyou,sitimenchou}
2 shiki_eiki {shikieiki_yamaxanadu,sikieiki_yamaxanadu}
2 shikinami_asuka_langley {shikinami_asuka_langly,shikinami_asuka_langely}
2 shimotsuki_potofu {potofu-chan_(pepepe),perooda_potofu}
2 shin'ya_(shin'yanchi) {shinya_(artist),shinya_(shinyanchi)}
3 shin_megami_tensei_iii:_nocturne {shin_megami_tensei:_nocturne,shin_megami_tensei:_lucifer's_call,shin_megami_tensei_nocturne}
2 shindou_l {shindoul,shindou_eru}
2 shinkon_gattai_godannar!! {god_soul_combination_godannar!!,god_soul_combination_godannar}
2 shinkon_gattai_godannar!! {marriage_of_god_and_soul_godannar!!,marriage_of_god_and_soul_godannar}
2 shinkon_gattai_godannar!! {shinkon_gattai_godannar!,shinkon_gattai_godannar}
2 shishiou_gai {shishioh_guy,shishioh_gai}
2 shockwave {blast_wave,blastwave}
2 shoken_narai {syokennnarai,syokennarai}
2 shop {store,shops}
2 short_dress {mini_dress,minidress}
2 short_hair {shorthair,short-hair}
2 short_shorts {hot_pants,hotpants}
2 shouji_ayumu {sasa_(pixiv),syouji_ayumu}
2 shoulder_pads {shoulder_pad,shoulderpads}
3 shugo_chara! {shugo_chara,shugo_kyara!,shugo_kyara}
2 shushing {shh,shush}
2 shuuji_(saishuu_heiki_kanojo) {shuuji_(saikano),shuji_(character)}
2 side_ponytail {sidetail,side_tail}
3 sideboob {sideboobs,side_boobs,side_boob}
2 simple_background {/simplebg,/sbg}
2 single-lens_reflex_camera {single_lens_reflex_camera,slr_camera}
2 sister_princess {sispri,sisterprincess}
2 sitting {sit,sitting_down}
2 sitting_on_face {face_sitting,facesitting}
2 skin_tight {skintight,skintightsuit}
2 skirt_basket {dress_basket,dress_carry}
2 skirt_lift {lift_skirt,lifted_skirt}
2 sleeve_cuffs {cuff_sleeve,cuff_sleeves}
3 sleeves_rolled_up {rolled_up_sleeves,rolled-up_sleeves,rolled_sleeves}
2 sono_hanabira_ni_kuchizuke_wo {sonohana,sono_hanabira_ni_kuchiduke_o}
3 sora_no_woto {sora_no_oto,so-ra-no-wo-to,so_ra_no_wo_to}
3 sora_wo_kakeru_shoujo {sorakake_girl,sora_o_kakeru_shoujo,sora_kake_girl}
2 source_request {no_source,need_source}
4 souryuu_asuka_langley {sohryu_asuka_langley,soryuu_asuka_langly,souryuu_asuka_langly,soryu_asuka_langley}
2 souryuu_asuka_langley_(cosplay) {soryu_asuka_langley_(cosplay),souryuu_asuka_langley_(cosplay)}
3 space_craft {spacecraft,spaceship,space_ship}
2 spider-man {spiderman,spider_man}
3 spider_web {spider_webs,spiderwebs,spiderweb}
2 spider_web {cobweb,cobwebs}
2 spiked_hair {spikey_hair,spiky_hair}
2 spread_anus {anus_spread,anus_spreading}
3 squatting {crouched,crouching,crouch}
3 stairs {staircase,stair,steps}
2 standing_on_one_leg {on_one_foot,on_one_leg}
2 starry_background {/starrybg,/starbg}
2 stasis_tank {cloning_tank,cloning_vat}
2 stitched {stiched,stitch}
2 straitjacket {straight_jacket,straightjacket}
2 strap-on {strapon,strap_on}
2 striped_panties {shimapan,stripped_panties}
2 studded_belt {studbelt,stud_belt}
3 stuffed_animal {plushy,plushies,plushie}
2 sugar_cube {sugar_cube_(object),sugar_cubes}
3 suiheisen_made_nan_mile? {suiheisen_made_nanmairu,suiheisen_made_nan_mile,suiheisen_made_nanmairu?}
2 suiheisen_made_nan_mile? {deep_blue_sky_&_pure_white_wings,deep_blue_sky_and_pure_white_wings}
3 sundress {summer_dress,sun_dress,summerdress}
2 super_danganronpa_2 {dangan-ronpa_2,dangan_ronpa_2}
2 super_danganronpa_2 {super_dangan-ronpa_2,super_dangan_ronpa_2}
2 super_mario_bros. {super_mario_bros,super_mario_brothers}
2 super_robot_wars_original_generation {/srwog,/swrog}
8 super_smash_bros. {super_smash_brothers_brawl,super_smash_bros_brawl,super_smash_bros,super_smash_brothers_melee,super_smash_bros_melee,super_smash_bros._brawl,super_smash_brothers,super_smash_bros._melee}
3 super_smash_bros. {/ssbb,/ssb,/ssbm}
3 super_sonico {sonico,soniko,super_soniko}
2 suppressor {silencer,sound_suppressor}
3 surprised {surprise,shock,shocked}
2 suzuki_ayane {cyneria,cineria}
3 sweatband {sweat_band,sweatbands,sweat_bands}
3 sweatdrop {sweatdrops,sweat_drops,sweat_drop}
2 sweet_potato {yams,yam}
2 swim_briefs {speedo,swimming_briefs}
2 swim_cap {swimming_cap,swimcap}
2 swim_trunks {swimtrunks,swimming_trunks}
2 swimsuit {swimsuits,swim_suit}
2 t-shirt {tshirt,t_shirt}
2 table_tennis {ping_pong,ping-pong}
4 table_tennis_paddle {ping-pong_paddle,ping_pong_racket,ping-pong_racket,ping_pong_paddle}
2 tail {animal_tails,animal_tail}
3 tail_bell {tailbell,tailbells,tail_bells}
2 tail_wagging {wagging_tail,wagging}
2 takahashi_fuuko {girl_behind_mio_at_opening_ceremony_(k-on!),girl_behind_mio_at_opening_ceremony}
2 takeshi_(pokemon) {brock,brock_(pokemon)}
2 tally {tallies,tally_marks}
2 tamaki_shin'ichirou {tamaki_shinichiro,tamaki_shinichirou}
2 tan {tanned_skin,tanned}
2 tanaka_kaori {soraya_saga,sorayasaga}
2 tanaka_takayuki {taka_tony,tony_taka}
3 tanline {tan_lines,tanlines,tan_line}
2 tarot {tarot_card,tarot_cards}
3 task_owner {tasukuoona,task_ohna,tasuku_oona}
2 tassel {tassle,tassels}
2 tattoo {tatoo,tattoos}
2 teacup {tea_cup,teacups}
2 teletha_testarossa {tessa_testatossa,teresa_testarossa}
3 ten'ou_haruka {tenoh_haruka,tenou_haruka,tennou_haruka}
2 ten'ou_haruka_(cosplay) {tennou_haruka_(cosplay),tenou_haruka_(cosplay)}
2 tenchi_muyou! {tenchi_muyou,tenchi_muyo}
3 tenkuu_no_shiro_laputa {laputa,laputa:_castle_in_the_sky,laputa_castle_in_the_sky}
3 tennousu_athena {tennousu_athene,tennousu_atene,tenoushuu_athena}
2 tennousu_athena {athena_tennousu,athena_tennos}
2 tenshi_no_inai_12-gatsu {tenshinoinai,tenshi_no_inai_12_gatsu}
2 tenshi_no_shippo {angel_tail,angel_tales}
2 testicle_licking {licking_testicles,lick_balls}
2 tetsuwan_atom {astro_boy,astroboy}
2 thick_thighs {thighthick,thunder_thighs}
2 thigh_boots {thighhigh_boots,thighboots}
2 thigh_sex {intercrural,intercrural_sex}
2 thigh_sex {straddle_penis,sumata}
3 thigh_strap {thigh_straps,thighband,thigh_band}
6 thighhighs {thigh_highs,thighhigs,thighhighs_only,thighhgihs,thighighs,thighhigh}
2 thighhighs {stockings,stocking}
2 thighhighs {naked_thighhighs,nude_thighhighs}
2 thomas_light {dr_light,dr._light}
2 tier_harribel {tia_halibel,tia_harribel}
2 tiger_&_bunny {tiger&bunny,tiger_and_bunny}
2 tileable {tessellation,tileable_background}
2 tinker_bell {tsukiyo_chakai,tinkle}
2 tio_(konjiki_no_gash!!) {tio_(zatch_bell),tio_(konjiki_no_gash)}
5 tiptoes {tip-toes,tip_toe,tip_toes,tip-toe,tiptoe}
3 to_love-ru {toloveru,to_love_ru,to-love-ru}
2 toe_scrunch {curled_toes,clenched_toes}
2 toe_scrunch {toe_curl,toe-scrunch}
2 togashi_yuuta's_mother {togashi_(mother),togashi_mother}
2 toki_towa {time_and_eternity,toki_to_towa}
3 toki_wo_kakeru_shoujo {the_girl_who_leapt_through_time,tokikake,toki_o_kakeru_shoujo}
2 tombstone {grave_stone,gravestone}
2 tonegawa_anju {angela_thompson,angie_thompson}
2 top-down_bottom-up {top-down-bottom-up,top_down_bottom_up}
3 top_wo_nerae! {top_o_nerae,top_o_nerae!,top_wo_nerae}
3 top_wo_nerae_2! {top_o_nerae_2,top_wo_nerae_2,top_wo_nerae!_2}
2 top_wo_nerae_2! {gunbuster2,gunbuster_2}
2 torii {torii_gate,torii_(gate)}
2 torn_clothes {ripped_clothes,ripped_clothing}
2 torn_clothes {torn_clothing,tornclothes}
2 toshi_punk {toshi_(tsujigiri_style),toshi_(pixiv62797)}
2 touei {toei_animation,toei}
2 touge_(kubiwa_tsuki) {touge369,touge36⑨}
2 translated {translation,translatied}
3 translation_request {translationrequest,translate_request,translation_requested}
2 transparent_background {/tbg,/transparentbg}
2 transparent_background {transparent_gif,transparent_png}
2 trash_bag {garbage_bags,garbage_bag}
2 trash_bag {rubbish_bags,rubbish_bag}
2 trash_bag {waste_bags,waste_bag}
2 trembling {shiver,shivering}
2 tsuwabuki_daigo {steven_(pokemon),steven_stone}
3 twin_braids {twinbraid,twin_braid,twinbraids}
3 twintails {twintaiks,twin_tails,twintail}
2 two-tone_hair {two-tone-hair,two_tone_hair}
2 type-moon {type_moon,typemoon}
2 uchuu_senkan_yamato {star_blazers,space_battleship_yamato}
2 ukiyo-e {ukiyoe,ukiyo_e}
2 ulquiorra_cifer {ulquiorra_schiffer,ulquiorra}
3 ultimate_girl {ultimategirls,ultimategirl,ultimate_girls}
2 umeboshi_(lazy_lazy) {noein_(artist),noein_(lazy_lazy)}
2 uncensored {descensored,decensored}
2 under_table {under_the_table,under_desk}
2 underboob {under_boob,underbreast}
2 undressing {strip,stripping}
2 upside-down {upside_down,upsidedown}
2 urushihara_satoshi {/su,/us}
3 utsugi_(pokemon) {prof_elm,professor_elm,prof._elm}
4 valentine {valentines,valentien,valentines_day,valentine's_day}
2 vampire_(game) {dark_stalkers,darkstalkers}
2 vampire_(game) {vampire_savior,vampire_saviour}
2 vector_trace {vectortrace,vector}
2 veins {vein,veiny}
2 venus_symbol {copper_sign,copper_symbol}
2 venus_symbol {female_symbol,female_sign}
2 vertical_stripes {vertical_striped,vertically_striped}
2 victoreem_(konjiki_no_gash!!) {victoreem_(konjiki_no_gash),victoreem_(zatch_bell)}
3 victorica_de_blois {victorica_de_broix,victorique_de_broix,victorique_de_blois}
3 video_game {videogames,videogame,video_games}
5 videocasette {video_tape,video_cassette,vhs_cassette,vhs,videotape}
2 vista-tan {vista,vis-tan}
2 vocaloid {vocaloid_2,vocaloid_3}
2 wakamezake {lap_cup,lapcup}
2 walpurgisnacht_(madoka_magica) {walpurgis_no_yoru_(madoka_magica),walpurgis_night_(madoka_magica)}
3 walther_wa_2000 {walther_wa-2000,wa-2000,wa2000}
2 wariza {w_sitting,w-sitting}
2 watanabe_akio {poyoyonrock,poyoyon_rock}
4 water_drop {raindrops,rain_drop,rain_drops,raindrop}
2 water_gun {water_pistol,watergun}
2 watercolor_(medium) {watercolor,watercolour}
2 watercolor_pencil_(medium) {watercolor_pencil,watercolour_pencil}
2 watering_can {watering_pail,watering_pot}
2 wemu_(ivycrown) {emu_(xxemuxx),eizou_toka_iroiro}
2 wet_clothes {wet_clothing,wetclothes}
2 white_background {/whitebg,/wbg}
5 white_legwear {white_thighhighs,white_pantyhose,white_leggings,white_kneehighs,white_socks}
2 white_school_swimsuit {white_sukumizu,white_school_swimsuits}
2 wide-eyed {wide_eyed,wide_eyes}
2 witch_hat {witches_hat,witchhat}
3 wrist_cuffs {wristcuffs,wristcuff,wrist_cuff}
3 wristband {wrist_bands,wrist_band,wristbands}
2 x-ray {x_ray,xray}
5 yahari_ore_no_seishun_lovecome_wa_machigatteiru. {yahari_ore_no_seishun_lovecome_ha_machigatteiru.,yahari_ore_no_seishun_rabukome_wa_machigatteiru,yahari_ore_no_seishun_love_come_wa_machigatteiru,yahari_ore_no_seishun_lovecome_wa_machigatteiru,yahari_ore_no_seishun_love_come_wa_machigatteiru.}
2 yamato_nadeshiko_shichi_henge {yamato_nadeshiko_shichihenge,yamatonadeshiko_shichihenge}
3 yaoi {boys_love,boy's_love,boy_love}
2 yaoi {shounen-ai,shonen-ai}
2 yellow_eyes {hazel_eyes,hazeleyes}
5 yellow_legwear {yellow_socks,yellow_leggings,yellow_thighhighs,yellow_pantyhose,yellow_kneehighs}
4 yin_yang {ying_yang,ying-yang,yinyang,yin-yang}
2 yojouhan_shinwa_taikei {tatami_galaxy,the_tatami_galaxy}
2 yotsubato! {yotsubato,yotsuba&!}
3 ys_seven {ys7,ys_7,ys_vii}
3 yuri {girl_love,girl's_love,girls_love}
7 yuu-gi-ou {yugioh!,yuugioh,yu-gi-oh,yu-gi-ou!,yu-gi-ou,yu-gi-oh!,yugioh}
2 yuuki_makoto {protagonist_(persona_3),protagonist_(persona3)}
2 yuusha_raideen {brave_reideen,brave_raideen}
2 zhang_wei_yi {z-w-y,zwy-001}

Though I haven't looked through the whole list I don't see much in the way of very different aliases. They're mostly just minor spelling variations.

There's this when you search for t*_hair:
turquoise_hair -> aqua_hair
teal_hair -> aqua_hair

1 2 3