Optimize Mysql query with Sub Select

Asked

Viewed 27 times

0

I was having a problem of slowness in a select as below:

    select 
      vendas.codigo, vendas.cartao_tipo, vendas.valor, 
      vendas.datavenda, venda.autorizacao,
      cliente.codigo, cliente.nome, cliente.cpf,
      cartao.numero_final, cartao.nome,
      plano.nome, plano.max_parcela
    from mv_vendas vendas
    inner join mv_clientes clientes on(clientes.codigo = vendas.cli_codigo)
    left join mv_cartoes cartao on(cartao.tipo = vendas.cartao_tipo)
    left join mv_planos plano on(plano.codigo = vendas.plano_codigo)
    where (vendas.datavenda between '2021-05-01' and '2021-05-31')
      and(vendas.status = 'sucesso')
    order by vendas.datavenda desc
    limit 100,50

This SELECT in a table of 150 thousand records (with the appropriate index in the aggregated fields) takes 2,600s on my local machine, when I put it on the server takes 0.312s, a huge difference

Taking into account that my server is a Xeon 8 Cores and 16GB of Memory with SSD at first I ended up accepting the difference...

But then I started thinking, wait a minute... my laptop is an i5 with 8GB of memory and SSD, it can’t take that long... that’s when I started doing SQL tests to see if it improved the result on my machine, because 150,000 records on a table is next to nothing... I’ve worked with DBF with 10 million records and it was almost instantaneous...

I started to see that Mysql was reading the whole table to bring me the result of order by e limit, because when I took them it was much faster.

But as I need to paginate and bring ordered by descending date so I arrived at the following SELECT:

    select 
      vendas.codigo, vendas.cartao_tipo, vendas.valor, 
      vendas.datavenda, venda.autorizacao,
      cliente.codigo, cliente.nome, cliente.cpf,
      cartao.numero_final, cartao.nome,
      plano.nome, plano.max_parcela
    from( 
      select * from mv_vendas
      where (datavenda between '2021-05-01' and '2021-05-31')
        and(status = 'sucesso')
      order by datavenda desc
      limit 100,50
    ) as vendas
    inner join mv_clientes clientes on(clientes.codigo = vendas.cli_codigo)
    left join mv_cartoes cartao on(cartao.tipo = vendas.cartao_tipo)
    left join mv_planos plano on(plano.codigo = vendas.plano_codigo)
    

Analyzing, it makes sense because now I’m searching in the mv_sales table only what I really need and then I put together the aggregated tables data

Result: On my machine it makes the SELECT in 0.035s and on the server 0.032s

I am putting here on Stack to receive criticism from colleagues to know if I am on the right track because I am far from being a DBA, but I want to get the best that I can from the database when it comes to search time.

If you have suggestions so that I can improve this SELECT there, I am all ears.

Note. The tables mv_cards and mv_plans will not always have sales records so the use of left.

  • I’m not an expert on DB, but I think for someone to be able to answer you, you need to know 1) how the tables are; 2) how the query execution plan is; 3) which is the DBMS. By the way, the text got confused,?

  • The two return what I need, the problem is only the response time... and the SGDB is Mysql

  • Clearly the response time is good, especially compared to the first query. I didn’t understand the doubt, it seems that you asked the question and the answer together.

  • I’d like to make sure I’m on the right track, because sometimes we think a select is fine by the response time, but the passage of time can show that this select would not bring the correct result from the base, leaving some record behind, so I posted.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.