mysql - My JOIN query on multiple tables is very slow -
my current query advanced search takes 60 secs complete. suggestions improving this? database: mysql webserver: apache - php (pdo)
current code structure:
select b.title, count(*) num library.physicalinfo left join library.bibliographicinfo b on a.bookid = b.bibliographicinfoid left join library.authors c on b.bibliographicinfoid = c.bookid left join library.bookauthors d on c.bookauthorid = d.personid left join library.series e on b.bibliographicinfoid = e.bookid left join library.bookslocation f on a.location = f.booklocationid left join library.publishstatement g on b.bibliographicinfoid=g.bookid left join library.publisher h on g.publisherid = h.publisherid ( b.title '%سلام%' or d.name '%سلام%' or f.location '%سلام%' or g.place '%سلام%' or g.year '%سلام%' or h.name '%سلام%' ) limit 0, 30
i've created indexes fields used in join comparisons , where
statements:
create index personid on library.bookauthors(personid); ....
my table structures are:
mysql> describe physicalinfo; +----------------+--------------+------+-----+---------+----------------+ | field | type | null | key | default | | +----------------+--------------+------+-----+---------+----------------+ | physicalinfoid | int(11) | no | pri | null | auto_increment | | volume | varchar(10) | yes | | null | | | section | varchar(100) | yes | | null | | | year | varchar(10) | yes | | null | | | registerno | varchar(20) | yes | | null | | | barcode | varchar(45) | yes | mul | null | | | location | int(11) | yes | mul | null | | | bookid | int(11) | yes | mul | null | | | version | varchar(10) | yes | | null | | +----------------+--------------+------+-----+---------+----------------+ mysql> describe bibliographicinfo; +------------------------+---------------+------+-----+---------+----------------+ | field | type | null | key | default | | +------------------------+---------------+------+-----+---------+----------------+ | bibliographicinfoid | int(11) | no | pri | null | auto_increment | | lcno | varchar(45) | yes | | null | | | devino | varchar(45) | yes | | null | | | title | varchar(200) | yes | mul | null | | | isbn | varchar(20) | yes | mul | null | | | language | int(11) | yes | | null | | | isreference | smallint(6) | yes | | null | | +------------------------+---------------+------+-----+---------+----------------+
explain extended
result:
*************************** 1. row *************************** id: 1 select_type: simple table: type: possible_keys: null key: null key_len: null ref: null rows: 348390 filtered: 100.00 extra: null *************************** 2. row *************************** id: 1 select_type: simple table: b type: eq_ref possible_keys: primary,bibliographicinfoid key: primary key_len: 4 ref: library.a.bookid rows: 1 filtered: 100.00 extra: null *************************** 3. row *************************** id: 1 select_type: simple table: c type: ref possible_keys: bookid_idx,bookid key: bookid_idx key_len: 5 ref: library.b.bibliographicinfoid rows: 1 filtered: 100.00 extra: null *************************** 4. row *************************** id: 1 select_type: simple table: d type: eq_ref possible_keys: primary,personid key: primary key_len: 4 ref: library.c.bookauthorid rows: 1 filtered: 100.00 extra: null *************************** 5. row *************************** id: 1 select_type: simple table: e type: ref possible_keys: bookid key: bookid key_len: 5 ref: library.b.bibliographicinfoid rows: 2 filtered: 100.00 extra: using index *************************** 6. row *************************** id: 1 select_type: simple table: f type: eq_ref possible_keys: primary,booklocationid key: primary key_len: 4 ref: library.a.location rows: 1 filtered: 100.00 extra: null *************************** 7. row *************************** id: 1 select_type: simple table: g type: ref possible_keys: book_idx,bookid key: book_idx key_len: 5 ref: library.b.bibliographicinfoid rows: 1 filtered: 100.00 extra: null *************************** 8. row *************************** id: 1 select_type: simple table: h type: eq_ref possible_keys: primary,publisherid key: primary key_len: 4 ref: library.g.publisherid rows: 1 filtered: 100.00 extra: using 8 rows in set, 1 warning (0.00 sec)
my current query (on 5million records) takes 60 secs! question is:
- what doing wrong here?
- why first row in
explain extended
hastype=all
? far know, worsttype
, shouldn't there because i've created indexesbookid
,primary key
of table.
- the first thing think indexes. if choose them wisely can improve performance significantly. see here.
- sometimes should consider flattening tables. way break relational database rules of normalization gain speed performing less "joins".
- yet way use: if 1 of table hasn't many values, can in separate query, moving "join" field key, (caching array) , perform join after query execution when fetching records in php(or other language) code
- and approach perform job on time basis prepare data , insert table, ready fetching(not possible in many use cases due delay)
and can store values in cache.
Comments
Post a Comment