问题
I have a table containing key-value pairs which I would like to be ale to search efficiently on:
SELECT * WHERE meta_key = "User ID" AND meta_value = "123userId";
However due to a legacy requirement the key and value NVARCHAR storage might be as large as 255 and 1000 characters respectively. Indexing on such large columns is not only costly but also outright restricted on some db types.
I believe MySQL has a system to allow indexes by a LEFT
-style substring as follows:
CREATE INDEX ix_metadata_indexing_key_value ON metadata_indexing(meta_key, meta_value(255));
...however our system must support all three of MySQL, MSSQL and Oracle. Is this the right way to go about this, and if so, how do I make similar indexes on MSSQL and Oracle?
回答1:
If you are talking about WordPress, that index is only part of the solution. When reaching into postmeta
, you need a composite key starting with post_id
. More recommendations here .
Also, if the data is predictable enough, you might be able to replace the LONGTEXT
will something more civilized, like VARCHAR(150)
. Do SELECT MAX(LENGTH(meta_key)), MAX(LENGTH(meta_value)) FROM post_meta;
.
(I, too, pan EAV. And especially WP's poor implementation.)
回答2:
As @Larnu suggested we ended up with a new computed meta_value_short
column which needed to be produced separately for each db type. When querying...
If the length is 255 or less: Simply compare to meta_value_short
.
Otherwise: first compare LEFT(value, 255)
to meta_value_short
, then additionally compare with meta_value
.
For reference the computed column definitions are below:
MSSQL:
ALTER TABLE [metadata_indexing] ADD meta_value_short AS (SUBSTRING(meta_value, 1, 255))
MySQL:
ALTER TABLE metadata_indexing ADD meta_value_short VARCHAR(255) AS (SUBSTRING(meta_value, 1, 255));
Oracle:
ALTER TABLE metadata_indexing ADD meta_value_short AS (SUBSTR(meta_value, 1, 255));
来源:https://stackoverflow.com/questions/65112973/how-can-i-create-an-index-on-the-substring-of-a-column