mysql - How to optimize this SQL query? (Movie Database) -
i'm using mysql , reason takes lot of time execute queries this:
select distinct (movies.id) id, movies.unmoid unmoid, movies.runtime runtime movies inner join acted on acted.unmoid = movies.unmoid inner join actors on acted.unmoactorid = actors.unmoactorid inner join directed on directed.unmoid = movies.unmoid inner join directors on directed.unmodirectorid = directors.unmodirectorid actors.name '%spiderman%' or directors.name '%spiderman%' or movies.originaltitle '%spiderman%' or movies.englishtitle '%spiderman%' or movies.alsoknownas '%spiderman%' or movies.taglines '%spiderman%' or movies.plot '%spiderman%' , movies.validated =1 , movies.agecertificate <=20 group movies.id order added desc
this give me: "executed query in 6.5320 seconds , got 2 result(s)."
explain particular query gives:
id select_type table type possible_keys key key_len ref rows 1 simple movies unmoid null null null 925 using temporary; using filesort 1 simple directed ref unmoid,unmodirectorid unmoid 62 movies.movies.unmoid 1 1 simple directors eq_ref unmodirectorid unmodirectorid 62 movies.directed.unmodirectorid 1 1 simple acted ref unmoid,unmoactorid unmoid 62 movies.movies.unmoid 34 1 simple actors eq_ref unmoactorid unmoactorid 62 movies.acted.unmoactorid 1 using
profiling info:
...... creating tmp table 0.000032 sorting group 0.000007 executing 0.000005 copying tmp table 6.324177 sorting result 0.000027 sending data 0.000019 ......
in worst cases takes 20 seconds execute query , every time of time goes copying tmp table
. so, optimize queries , reasonable query times.
i have indexes for:
movies.id primary movies.unmoid unique movies.runtime index acted.unmoid index acted.unmoactorid index actors.unmoactorid unique actors.name uindex directed.unmoid index directed.unmodirectorid index directors.unmodirectorid unique directors.name index movies.originaltitle index movies.englishtitle index movies.alsoknownas index movies.taglines index movies.plot index
i think reason slowness because condition wide. instead, i'd try out making simple queries , combine them union
, weed out duplicates.
so, might beneficial (i can't test claim because don't have db), because assume each individual query quite fast, , there not many records merge:
(select movies.id, movies.unmoid, movies.runtime, added movies inner join actors on acted.unmoactorid = actors.unmoactorid actors.name '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) union (select movies.id, movies.unmoid, movies.runtime, added movies inner join directed on directed.unmoid = movies.unmoid inner join directors on directed.unmodirectorid = directors.unmodirectorid directors.name '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) union (select movies.id, movies.unmoid, movies.runtime, added movies movies.originaltitle '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) union (select movies.id, movies.unmoid, movies.runtime, added movies movies.englishtitle '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) union (select movies.id, movies.unmoid, movies.runtime, added movies movies.alsoknownas '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) union (select movies.id, movies.unmoid, movies.runtime, added movies movies.taglines '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) union (select movies.id, movies.unmoid, movies.runtime, added movies movies.plot '%spiderman%' , movies.validated =1 , movies.agecertificate <=20) order added desc
you need include fields want sort on, or filter on, in query result.
and if have engine supports subselects, can move filter conditions validation , age certification out of individual queries , common wrapper query, benefit removal of repetition, thus, maintenance:
select id, unmoid, runtime (select ... ) q -- above query including necessary fields movies.validated =1 , movies.agecertificate <=20 order added desc
Comments
Post a Comment