Reputation: 1699
Hi everyone I have the following database:
`Users`
'id', 'char(36)', 'NO', 'PRI', NULL, ''
'password', 'varchar(64)', 'NO', '', NULL, ''
'email', 'varchar(60)', 'NO', 'UNI', NULL, ''
'roles', 'longtext', 'NO', '', NULL, ''
'is_active', 'tinyint(1)', 'NO', '', NULL, ''
`Galleries`
'id', 'char(36)', 'NO', 'PRI', NULL, ''
'user_id', 'char(36)', 'NO', 'MUL', NULL, ''
'name', 'varchar(255)', 'NO', '', NULL, ''
'description', 'longtext', 'YES', '', NULL, ''
'created_at', 'datetime', 'NO', '', NULL, ''
`Images`
'id', 'char(36)', 'NO', 'PRI', NULL, ''
'gallery_id', 'char(36)', 'YES', 'MUL', NULL, ''
'original_filename', 'varchar(255)', 'NO', '', NULL, ''
'filename', 'varchar(255)', 'NO', '', NULL, ''
'description', 'longtext', 'YES', '', NULL, ''
And the following query:
SELECT gal.name, gal.description, img.filename, img.description FROM `homestead`.`users` AS users
LEFT JOIN `homestead`.`galleries` AS gal ON users.id = gal.user_id
LEFT JOIN `homestead`.`images` AS img on img.gallery_id = gal.id
WHERE img.description LIKE '%dog%';
When using explain
in this query I get the index
result in the type
field of the Users query. My question is, is there any way to improve this query so it improves this result. I understand the index
means it goes through all the entries on that particular table, and that may be necessary in this case.
But do you guys see other ways of improving this?
EDIT: Showing indexes for galleries and images tables:
Galleries:
'galleries', '0', 'PRIMARY', '1', 'id', 'A', '1', NULL, NULL, '', 'BTREE', '', ''
'galleries', '0', 'UNIQ_F70E6EB7BF396750', '1', 'id', 'A', '1', NULL, NULL, '', 'BTREE', '', ''
'galleries', '1', 'IDX_F70E6EB7A76ED395', '1', 'user_id', 'A', '1', NULL, NULL, '', 'BTREE', '', ''
Images:
'images', '0', 'PRIMARY', '1', 'id', 'A', '4', NULL, NULL, '', 'BTREE', '', ''
'images', '0', 'UNIQ_E01FBE6ABF396750', '1', 'id', 'A', '4', NULL, NULL, '', 'BTREE', '', ''
'images', '1', 'IDX_E01FBE6A4E7AF8F', '1', 'gallery_id', 'A', '4', NULL, NULL, 'YES', 'BTREE', '', ''
And the explain on the query already without the Users table:
'1', 'SIMPLE', 'gal', NULL, 'ALL', 'PRIMARY,UNIQ_F70E6EB7BF396750', NULL, NULL, NULL, '1', '100.00', NULL
'1', 'SIMPLE', 'img', NULL, 'ref', 'IDX_E01FBE6A4E7AF8F', 'IDX_E01FBE6A4E7AF8F', '109', 'homestead.gal.id', '1', '25.00', 'Using where'
Upvotes: 0
Views: 71
Reputation: 142316
(This partially disagrees with Gordon's answer.)
Since the WHERE
only mentions images
(WHERE i.description LIKE '%dog%'
), the Optimizer will probably start with that table. No regular index is useful for that. (Gordon's comment on FULLTEXT
is the 'right' way to improve that.)
The second table is easy to get to if id
is the PRIMARY KEY
. Please provide SHOW CREATE TABLE
so we can see what indexes you have.
(I agree with the rest of Gordon's Answer.)
Another issue... If the tables become 'huge', you will find that UUIDs perform poorly (because of the randomness). A million rows is OK, a billion rows will be very slow.
Upvotes: 1
Reputation: 1270091
First, you can change the left join
to inner join
-- the where
clause is already doing that, but be explicit. You can also get rid of users
, because it is not used.
SELECT g.name, g.description, i.filename, i.description
FROM `homestead`.`galleries` g INNER JOIN
`homestead`.`images` i
ON i.gallery_id = g.id
WHERE i.description LIKE '%dog%';
This query should be fine with indexes on images(gallery_id)
.
If performance is really an issue, you may want to investigate full text indexes so you can possibly change the like
to match()
.
Upvotes: 1