EAV
таблица - хорошая вещь, если вам не нужно искать несколько значений одновременно, и в этом случае она становится плохой.
Вы не можете индексировать несколько значений одновременно, потому что они находятся в разных записях.
В таблице SQL Server
вы можете создать индексированное представление для нескольких значений и использовать его для поиска.
В Oracle
вы можете кластеризовать таблицу по UserID
, которая будет хранить все записи с одинаковым UserID
на одной странице данных, которая будет использовать индекс по наиболее селективному значению и быстро сканировать другие значения.
В PostgreSQL
вы можете хранить все значения в одном массиве и индексировать его с помощью индекса GIN
.
В MySQL
вы не можете сделать ничего из этого.
Вот запрос, который вернет значения:
SELECT *
FROM tbl_UserAttributes tcity
JOIN tbl_UserAttributes tsex
ON tsex.userid = tcity.userid
WHERE tcity.fieldname = 'city'
AND tcity.value LIKE '%Mumbai%'
AND tsex.fieldname = 'sex'
AND tsex.value = 'M'
но не ожидайте, что это будет очень быстро.
Обновление:
Если вам нужно точное совпадение, вы можете создать составной индекс на (fieldname, value, userid)
, поместить наиболее селективный fieldname
в первую таблицу и использовать STRAIGHT_JOIN
, чтобы форсировать порядок:
SELECT *
FROM tbl_UserAttributes tcity
STRAIGHT_JOIN
tbl_UserAttributes tsex
ON tsex.userid = tcity.userid
WHERE tcity.fieldname = 'city'
AND tcity.value = 'Mumbai'
AND tsex.fieldname = 'sex'
AND tsex.value = 'M'
Однако это не поможет с вашим текущим запросом, так как вы ищете совпадение с подстановочными знаками, в этом случае индексы не очень полезны. И ваша вторая таблица не получит много пользы от индекса, если вы не запросите базу данных роддома.
Тем не менее, это сэкономит вам некоторое время, поскольку сканирование таблицы можно использовать вместо сканирования таблицы.