WoltLab / WCF

WoltLab Suite Core (previously WoltLab Community Framework)
https://www.woltlab.com
GNU Lesser General Public License v2.1
238 stars 145 forks source link

Add explicit PRIMARY KEY for select heavy tables with a multi-column UNIQUE KEY #3803

Closed TimWolla closed 9 months ago

TimWolla commented 3 years ago

InnoDB uses the PRIMARY KEY as the clustered index for the btree. Without an explicit PRIMARY KEY an internal auto increment will be used, allowing the best INSERT performance because data always is appended to the end.

Setting an explicit PRIMARY KEY might reduce INSERT performance due to insertions in the middle, but will improve SELECT performance, because the data is stored continuously. In addition this removes the need for the secondary index, making the table smaller.

see also: https://www.percona.com/blog/2018/07/26/tuning-innodb-primary-keys/

We should leverage this for read heavy tables:

TimWolla commented 3 years ago
* `wcf1_like`:

The workload is not clear enough to justify a change here. In addition the INSERTs will be “all over the place” due to userID being part of the INDEX and users possibly reacting to oldish content.

TimWolla commented 3 years ago
* `wcf1_poll_option_vote`

This one is barely read from during normal operation. This does not justify a change.

TimWolla commented 3 years ago
* `wcf1_article_content`

That one already has a PRIMARY KEY that I must've missed.

TimWolla commented 3 years ago
* `wcf1_box_content`

Same here.

TimWolla commented 3 years ago
* `wcf1_page_content`

Same.

TimWolla commented 3 years ago
* `wcf1_user_collapsible_content`

This one is cached in user storage and there's the resetAll() method that includes a query that does not include the userID. I'm not that sure about the benefits of my suggestion here.

TimWolla commented 3 years ago

Use PRIMARY KEY (userID, trophyID)

* Inverted order, because I expect this to mostly search for trophies of a single user.

The table is queried with a DELETE on trophyID when a trophy is being disabled. I expect that to rarely happen.

TimWolla commented 3 years ago

Possibly add KEY (groupID)

* “find all users in group”.

This one was already created implicitly, because of the FOREIGN KEY.

TimWolla commented 3 years ago
* `wcf1_like_object`

Unfortunately that one also has a PRIMARY KEY with auto increment. And the contents of this table are mapped as a DatabaseObject, so we can't adjust this one either.

dtdesign commented 3 years ago
* `wcf1_like_object`

Unfortunately that one also has a PRIMARY KEY with auto increment. And the contents of this table are mapped as a DatabaseObject, so we can't adjust this one either.

Why is that a problem? The AUTO_INCREMENT is not required to be the PK.

TimWolla commented 3 years ago

Why is that a problem? The AUTO_INCREMENT is not required to be the PK.

Interesting. I was of the impression that this had to be the case. This changes everything :grin:

TimWolla commented 3 years ago

Moving this to 5.5 to revisit it then: