sql - MySQL query index & performance improvements -


i have created application track progress in league of legends me , friends. purpose, collect information current rank several times day mysql database. fetch results , show them in graph, use following query / queries:

select      lol_summoner.name name, grid.series + ? timestamp,      avg(nullif(lol.points, 0)) points      series_tmp grid join      lol on lol.timestamp >= grid.series , lol.timestamp < grid.series + ? join      lol_summoner on lol.summoner = lol_summoner.id group     lol_summoner.name, grid.series order     name, timestamp asc  select      lol_summoner.name name, grid.series + ? timestamp,      avg(nullif(lol.points, 0)) points      series_tmp grid join      lol on lol.timestamp >= grid.series , lol.timestamp < grid.series + ? join      lol_summoner on lol.summoner = lol_summoner.id      lol_summoner.name in (". str_repeat('?, ', count($names) - 1) ."?) group     lol_summoner.name, grid.series order     name, timestamp asc 

the first query used in case want retrieve players saved in database. grid table temporary table generated timestamps in specific interval retrive information in chunks of interval. 2 variable in query interval. second query used if want retrieve information specific players only.

the grid table produces following stored procedure called 3 parameters (n_first - first timestamp, n_last - last timestamp, n_increments - increments between 2 timestamps):

begin     -- create tmp table     drop temporary table if exists series_tmp;     create temporary table series_tmp (         series bigint     ) engine = memory;      while n_first <= n_last         -- insert in tmp table         insert series_tmp (series) values (n_first);          -- increment value 1         set n_first = n_first + n_increment;      end while; end 

the query works , finishes in reasonable time (~10 seconds) thankful improve query either rewriting or adding additional indexes database.

/edit:

after review of @rick james answer, modified queries follows:

select lol_summoner.name name, (lol.timestamp div :range) * :range + :half_range timestamp, avg(nullif(lol.points, 0)) points   lol     join lol_summoner on lol.summoner = lol_summoner.id   group lol_summoner.name, lol.timestamp div :range   order name, timestamp asc  select lol_summoner.name name, (lol.timestamp div :range) * :range + :half_range timestamp, avg(nullif(lol.points, 0)) points   lol     join lol_summoner on lol.summoner = lol_summoner.id   lol_summoner.name in (<names>)   group lol_summoner.name, lol.timestamp div " . $steps . "   order name, timestamp asc 

this improves query execution time margin (finished way under 1s).

problem 1 , solution

you need series of integers between 2 values? , differ 1? or larger value?

first, create permanent table of numbers 0 large enough value:

create table num10 ( n int ); insert num10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table nums ( n int, primary key(n))     select a.n*1000 + b.n*100 + c.n*10 + d.n         num10         join num10 b  -- note "cross join"         join num10 c         join num10 d; 

now nums has 0..9999. (make bigger if might need more.)

to sequence of consecutive numbers 123 through 234:

 select 123 + n nums n < 234-123+1; 

to sequence of consecutive numbers 12345 through 23456, in steps of 15:

 select 12345 + 15*n nums n < (23456-12345+1)/15; 

join select 1 of instead of series_tmp.

barring other issue, should speed things up.

problem 2

you grouping by series, ordering timestamp. related, might 'right' answer. think it.

problem 3

you seem building "buckets" (called "series"?) "timestamps". correct? if so, let's work backwards -- turn "timestamp" "bucket" number:

bucket_number = (timestamp - start) / bucket_size 

by doing throughout, can avoid 'problem 1' , eliminate solution it. is, reformulate entire queries in terms of buckets.


Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

c - Unrecognised emulation mode: elf_i386 on MinGW32 -