Couchbase Query with ORDER BY DESC and LIMIT is very slow - couchbase

select t.createdDate, t.createdDateTicks from ic_v10_mammoet t where t.type='asset' and t._sync.rev is not null ORDER BY t.createdDateTicks ASC LIMIT 10 OFFSET 0
The above query takes 6 seconds to return result and when I remove ORDER BY clause it take only 18 MS
select t.createdDate, t.createdDateTicks from ic_v10_mammoet t where t.type='asset' and t._sync.rev is not null LIMIT 10 OFFSET 0
I have an index on createdDateTicks and it is integer field.
I tried the workaround mentioned at workaround as last comment but that do not work.
Can someone please advise?
Index is:CREATE INDEX asset_createdDateTicks ON ic_v10_mammoet (createdDateTicks) WHERE type = 'asset'
Plan with ORDER BY and Plan without ORDER BY

Here is the workaround.
CREATE INDEX idx_neg_date ON docs( -createDateTicks ) WHERE type = 'asset';
SELECT t.createdDate, t.createdDateTicks
FROM docs AS t
WHERE t.type='asset' AND -t.createdDateTicks IS NOT NULL
ORDER BY -t.createdDateTicks ASC LIMIT 10 OFFSET 0;

Related

Below Sql query is taking too much time. How to make this faster?

SELECT
call_id
,call_date
,call_no
,call_amountdue
,rechargesamount
,call_penalty
,callpayment_received
,calldiscount
FROM `call`
WHERE calltype = 'Regular'
AND callcode = 98
AND call_connect = 1
AND call_date < '2018-01-01'
ORDER BY
`call_date` DESC
,`call_id` DESC
limit 1
Index is already there on call_date, callcode, calltype, callconnect
Table has 10 million records. Query is taking 2 min
How to get results within 3sec?
INDEX (calltype, callcode, call_connect, -- in any order
call_date, -- next
call_id) -- last
This will make it possible to find the one row that is desired without having to step over other rows.
Since you seem to have INDEX(calltype), Drop it; it will be in the way and, anyway, redundant. The rest of the indexes you mentioned will be ignored.
More discussion in Index Cookbook

This Query took 40 seconds anyway to speed its up ? the data in the database arent that many

so this query took 40 seconds to load, any way to speed it up? the framework that I used are Laravel and I need to show this data using ajax and this query took 40 seconds to load, I need to speed it up, I know the r.10 - r.13 the one that caused it I tested it out and found out that 3 are taking almost 20 secs to load
SELECT
`ms_paket_berjalan`.`kdPaketBerjalan` as `r1`,
`ms_pelanggan`.`namaLengkap` as `r2`,
`ms_rtrwnet`.`kabupaten` as `r3`,
`ms_paket_berjalan`.`jenis_pelanggan` as `r4`,
`ms_rtrwnet`.`nama` as `r5`,
DATE_FORMAT(ms_paket_berjalan.tglpasang, "%d/%m/%Y") as r6,
`ms_paket_berjalan`.`noTelp` as `r7`,
`ms_paket_berjalan`.`terverifikasi` as `r8`,
`ms_paket_berjalan`.`hargaPaket` as `r9`,
(
SELECT
COUNT(verifikasi_pelanggan.kdVerifikasi)
FROM
verifikasi_pelanggan
WHERE
verifikasi_pelanggan.kdPaketBerjalan = r1
) as r10,
(
SELECT
verifikasi_pelanggan.statusVerifikasi
FROM
verifikasi_pelanggan
WHERE
verifikasi_pelanggan.kdPaketBerjalan = r1
ORDER BY
kdVerifikasi DESC
LIMIT
1
) as r11,
(
SELECT
verifikasi_pelanggan.tanggalBa
FROM
verifikasi_pelanggan
WHERE
verifikasi_pelanggan.kdPaketBerjalan = r1
ORDER BY
kdVerifikasi DESC
LIMIT
1
) as r12,
(
SELECT
COUNT(verifikasi_pelanggan.noBa)
FROM
verifikasi_pelanggan
WHERE
verifikasi_pelanggan.kdPaketBerjalan = r1
) as r13
FROM
`ms_paket_berjalan`
inner join `ms_pelanggan` on `ms_pelanggan`.`kdPelanggan` = `ms_paket_berjalan`.`kdPelanggan`
inner join `ms_rtrwnet` on `ms_rtrwnet`.`kdRtRwNet` = `ms_pelanggan`.`kdRtRwNet`
inner join `tr_resellerisp` on `tr_resellerisp`.`kdRtRwNet` = `ms_rtrwnet`.`kdRtRwNet`
left join `verifikasi_pelanggan` on `ms_paket_berjalan`.`kdPaketBerjalan` = `verifikasi_pelanggan`.`kdPaketBerjalan`
WHERE
`tr_resellerisp`.`kdIsp` = '11'
and `ms_paket_berjalan`.`break` = '0'
and `ms_paket_berjalan`.`deleted` = '0'
and `ms_pelanggan`.`deleted` = '0'
and `ms_pelanggan`.`suspended` = '0'
and `tr_resellerisp`.`persetujuan` = '1'
and `ms_paket_berjalan`.`terverifikasi` = '0'
and (
`ms_rtrwnet`.`nama` like '%%'
or `ms_pelanggan`.`namaLengkap` like '%%'
)
GROUP BY
`ms_paket_berjalan`.`kdPaketBerjalan`
ORDER BY
`ms_paket_berjalan`.`tglpasang` DESC
LIMIT
20 offset 0
If you don't have an index on your verifikasi_pelanggan table, you need to.
To add an index run something like:
ALTER TABLE `verifikasi_pelanggan`
ADD INDEX `index4` (`kdPaketBerjalan` ASC, `kdVerifikasi` DESC)
Just do that once and things should speed up.
EDIT: Your query without an index will scan the entire verifikasi_pelanggan multiple times for every result. Since it has an ORDER BY clause, it isn't even limited to 20, it will need to scan for every result and THEN sort and then limit to 20 results.
An INDEX essentially pre-sorts the table. It can find matches on the indexed columns almost instantly, rather than scanning and reading every row to see if it is a match.
Just indexing on kdPaketBerjalan should help a lot, but since you order by kdVerifikasi it looks like you might have multiple matches on kdPaketBerjalan, which would require sorting. Including kdVerifikasi in the index will find it instantly.

Mysql limit when the whole list may change

I have a query that returns 10 items of a big list. For example:
SELECT * FROM users
WHERE user_is_block = 0
AND user_is_paid = 1
ORDER BY user_post_hour ASC, id ASC"
When I put limit ?, ? to get a part of this list each time, a problem happens. Imagine we get the first 10. The row with id 11, is the first one in the next request. But as we use ORDER BY user_post_hour, the id 11 may go up and become 10. So when second request is sent, we never see id 11.
Any idea?
It might be the problem with datatype soring, again cast your column value to an integer explicitly
SELECT * FROM users
WHERE user_is_block = 0
AND user_is_paid = 1
ORDER BY cast(user_post_hour as unsigned) ASC, id ASC
Use this trick.
SELECT * FROM users
WHERE user_is_block = 0
AND user_is_paid = 1
ORDER BY user_post_hour+0 ASC, id ASC

Slow Query Time in MySQL

The following query is overloading my system. It seems to be a problem with the rand(). I have seen other posts dealing with similar issues, but can't quite get them working in this problem. It is being run on a 10M+ row table. I know that the order by rand() is the issue, but after reading there seems to be an issue of the autoincrement (items.ID) increments by 2 not 1.
SELECT stores.phone, stores.storeID, stores.name, stores.ZIP,
stores.state,stores.city, storeID, GEOCODES.lon, GEOCODES.lat
FROM items
LEFT JOIN stores on stores.storeID = items.store_ID
LEFT JOIN GEOCODES on GEOCODES.address = CONCAT(stores.address1,', ',stores.ZIP)
WHERE stores.phone IS NOT NULL
GROUP BY items.store_ID
ORDER BY RAND( )
LIMIT 200
The other article that I was trying to follow was How can i optimize MySQL's ORDER BY RAND() function?, but can't seem to figure out how to adapt it to this query. Please note that this is done in PHP.
if I were you I would LIMIT first and then ORDER BY RAND() on the limited query.. that way you arent pulling everything out and randomizing it.. I have used this exact method to speed up my queries exponentially
SELECT *
FROM
( SELECT stores.phone, stores.storeID, stores.name, stores.ZIP,
stores.state,stores.city, storeID, GEOCODES.lon, GEOCODES.lat
FROM items
LEFT JOIN stores on stores.storeID = items.store_ID
LEFT JOIN GEOCODES on GEOCODES.address = CONCAT(stores.address1,', ',stores.ZIP)
WHERE stores.phone IS NOT NULL
GROUP BY items.store_ID
LIMIT 200
) t
ORDER BY RAND( )
Some proof:
CREATE table digits as (-- a digit table with 1 million rows)
1000000 row(s) affected Records: 1000000 Duplicates: 0 Warnings: 0
1.869 sec
SELECT * FROM digits ORDER BY RAND() LIMIT 200
200 row(s) returned
0.465 sec / 0.000 sec
SELECT * FROM (SELECT * FROM digits LIMIT 200)t ORDER BY RAND()
200 row(s) returned
0.000 sec / 0.000 sec
Using RAND() in your query has serious performance implications, avoiding it will speed up your query a lot.
Also since you're using php, randomizing the ordering using shuffle() w/ php may be a significantly quicker alternative to mysql.
See: http://php.net/manual/en/function.shuffle.php

mysql php query : why does a including not equal affect the results

In a mysql query with 5000 records,
in the table: subscriptions [id autoincrement int, name varchar64, archive tinyint4 ]
i'm passing the following sql
$sqlg = "SELECT * FROM subscriptions where archive != 1 order by id desc limit 0,24";
the above returns
records between 3061 - 3012
If i remove the where clause,
SELECT * FROM subscriptions order by id desc
it returns, records between 5066 - 5037 which is the correct result i'm looking for with archive having the value of NULL or 0.
Any ideas why this might be happening?
NULL is not the same as 0. It simply is unknown, so if you want to check for NULL also, use IS NULL
SELECT *
FROM subscriptions
where archive = 0 OR archive IS NULL
order by id desc
limit 0, 24