Closed TimWolla closed 9 months 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.
* `wcf1_poll_option_vote`
This one is barely read from during normal operation. This does not justify a change.
* `wcf1_article_content`
That one already has a PRIMARY KEY that I must've missed.
* `wcf1_box_content`
Same here.
* `wcf1_page_content`
Same.
* `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.
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.
Possibly add
KEY (groupID)
* “find all users in group”.
This one was already created implicitly, because of the FOREIGN KEY.
* `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.
* `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.
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:
Moving this to 5.5 to revisit it then:
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:
wcf1_article_content
:PRIMARY KEY (articleID, languageID)
.UNIQUE KEY (articleID, languageID)
.wcf1_box_content
:PRIMARY KEY (boxID, languageID)
.UNIQUE KEY (boxID, languageID)
.wcf1_like
:PRIMARY KEY (objectTypeID, objectID, userID)
.UNIQUE KEY (objectTypeID, objectID, userID)
.wcf1_like_object
:PRIMARY KEY (objectTypeID, objectID)
.UNIQUE KEY (objectTypeID, objectID)
.wcf1_media_content
:PRIMARY KEY (mediaID, languageID)
.UNIQUE KEY (mediaID, languageID)
.wcf1_page_box_order
:PRIMARY KEY (pageID, boxID)
.UNIQUE KEY pageToBox (pageID, boxID)
.wcf1_page_content
:PRIMARY KEY (pageID, languageID)
.UNIQUE KEY (pageID, languageID)
.wcf1_poll_option_vote
:PRIMARY KEY (pollID, optionID, userID)
.pollID
even is part of this table, because it can be derived fromoptionID
.pollID
column, the additional join when voting / listing votees shouldn't be too bad.UNIQUE KEY vote (pollID, optionID, userID)
.wcf1_tag_to_object
:UNIQUE KEY (objectTypeID, languageID, objectID, tagID)
objectID
in front oflanguageID
.languageID
can be derived fromtagID
.PRIMARY KEY (objectTypeID, objectID, tagID)
without any secondary indices should work.wcf1_user_collapsible_content
:PRIMARY KEY (userID, objectTypeID, objectID)
userID
to the front.userID
.UNIQUE KEY (objectTypeID, objectID, userID)
.wcf1_user_group_option_value
:PRIMARY KEY (groupID, optionID)
.UNIQUE KEY groupID (groupID, optionID)
.wcf1_user_special_trophy
:PRIMARY KEY (userID, trophyID)
UNIQUE KEY (trophyID, userID)
wcf1_user_to_group
:PRIMARY KEY (userID, groupID)
KEY (groupID)