MySQL ORDER BY CASE optimization - mysql

I looked over the internet, but I couldn't find a solution for this particular query. I have this query:
SELECT *
FROM profile
ORDER BY CASE WHEN country_geoname_id = 2635167
THEN 1 ELSE 0 END DESC,
score DESC
I want to know if it's possible to optimize this query by avoiding the filesort. I created an index for the columns (country_geoname_id and score), but it didn't help.
EXPLAIN SELECT:

You make your order condition not sargeable when put it inside a function.
What makes a SQL statement sargable?
if you want use index create an aditional boolean field isMyCountry and create an index for it
Then your query became:
SELECT *
FROM profile
ORDER BY isMyCountry,
score DESC

Related

SQL - How to select discontinuous rows from a table with one select?

`SELECT * FROM Post
WHERE Tid = Id
ORDER BY Time
LIMIT 0,1`
`SELECT * FROM Post
WHERE Tid = Id
ORDER BY Time
LIMIT start,offset;`
Can I use only one SELECT to complete this?
Just like
`SELECT * FROM Post
WHERE Tid = Id
ORDER BY Time
LIMIT 0,1 and start,offset;`
In this case combine the 2 sql statements in a union, since you cannot provide multiple limit clauses in a single select:
SELECT * FROM Post LIMIT 1,2
UNION ALL
SELECT * FROM Post LIMIT 5,6;
However, I would add an order by clause to the 2 select statements just to make 100% sure you know which records will be selected.
UPDATE: Technically you could do this in a single statement using a running counter and filtering on the counter in where. However, that would not really be a good idea from performance wise, since mysql would have to loop through all records within the table. It cannot know which records would satisfy the criteria. Limit clauses are better optmised.

Is there a way to do this query without the sub-select?

I'm not positive but I believe sub-selects are less than optimal (speedwise?).
Is there a way to remove this sub-select from my query (I think the query is self-explanatory).
select *
from tickers
where id = (select max(id) from tickers where annual_score is not null);
Would something like:
SELECT *
FROM ticker
WHERE annual_score IS NOT NULL
ORDER BY id desc
LIMIT 1
work?
That particular sub-select shouldn't be inefficient at all. It should be run once before the main query begins.
There are a certain class of subqueries that are inefficient (those that join columns between the main query and the subquery) because they end up running the subquery for every single row of the main query.
But this shouldn't be one of them, unless MySQL is severely brain-damaged, which I doubt.
However, if you remain keen to get rid of the subquery, you can order the rows by id (descending) and only fetch the first, something like:
select * from tickers
where annual_score is not null
order by id desc
limit 0, 1
Not too familiar with MySQL, but if you want to eliminate the subquery then you could try something like this:
select *
from tickers
where annual_score is not null
order by id desc
limit 1
I don't know if this is more or less performant as MySQL is not my background.

SQL query MATCH with alias and order by and optimize query

i'm using this query to search inside table:
SELECT
*,
MATCH(tags,title,description)
AGAINST ('hey you are you in' IN BOOLEAN MODE) AS score
FROM table
ORDER BY insert_datetime DESC, id DESC
what i need is to use the alias 'score' to order results, is this the right sintax?:
SELECT
*,
MATCH(tags,title,description)
AGAINST ('hey you are you in' IN BOOLEAN MODE) AS score
FROM table
ORDER BY score DESC, insert_datetime DESC, id DESC
is also there anyway to optimize this query ? better way to write that?
is this the right sintax?
Yes. As documented under SELECT Syntax:
A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses.
is also there anyway to optimize this query ? better way to write that?
If you don't need the relevance score in your resultset, you need not select it:
SELECT *
FROM table
ORDER BY MATCH(tags, title, description) AGAINST (
'hey you are you in' IN BOOLEAN MODE
) DESC, insert_datetime DESC, id DESC
But sadly, as suggested under ORDER BY Optimization, there is no way that MySQL can avoid undertaking a filesort when ordering by the result of a function such as MATCH() ... AGAINST():
In some cases, MySQL can use an index to satisfy an ORDER BY clause without doing any extra sorting.
The index can also be used even if the ORDER BY does not match the index exactly, as long as all of the unused portions of the index and all the extra ORDER BY columns are constants in the WHERE clause.
However, one could:
filter the resultset for only those records of interest by using a WHERE clause, thereby reducing the number of results that must be sorted; and/or
reduce the maximum number of comparisons each sorting step will need to perform by removing unneeded columns from the ORDER BY clause.

Order by performance problems

I have an index problem with my order by statement. I have this query witch is runing fast:
SELECT name from members where kat = 2 order by date DESC;
I have a composite index on members table:
kat_index(kat,date);
Now my aplication has changed and i have added a query like this:
SELECT name from members where kat = 2 order by logged_in DESC, status DESC, date DESC;
Now the query i slow because it's using filesort. So the question is... What type of index should i add to satisfy both queries?
You should have two indexes:
(kat, date)
(kat, logged_in, status, date)
Each query will use the index that is best for that query.
You cannot cover both queries with one index. You must form a leftmost prefix on the composite index along with the ORDER BY clause as well.

how to speed up mysql query with two order by filters

select * from mytable order by first_col desc, sec_col asc limit 1;
when using only one order by filter, the query finished rather quickly(a few seconds), but the above query took hours. would a two column index speed this up? is there any way to speed up the query?
No, for now there is no solution to optimize "ORDER BY ... ASC, ... DESC". Mysql cannot create indexes with sorting order different than ASC.
ps: yes, I know it is a sorting order parameter in create index but it still doesn't work and was added to satisfy some ansi sql requirements.