How to give optimizer hints on DDL query ?
I have a use case to set lock_wait_timeout in an alter query. I do prefer to give it for that statement alone. Is it possible to give optimizer hint in the same statement itself?
PS : I do not prefer setting lock_wait_timeout for that entire session.
Related
Consider this UPDATE statement:
UPDATE `messages` force index (primary)
SET `isDeleted`=1
WHERE `messages`.`id` = '069737b6-726d-4f5b-a5b9-0510acdd7a92';
Here's the explain graph for it:
Why this simple query uses index range scan instead of single row fetch or at least unique key fetch? Notice that I use FORCE INDEX and exactly same query written as SELECT statement results in "Single Row (constant)" scan.
Also same happens if I add LIMIT 1
I'm using mysql 5.6.46
MySQL ignores index hints in UPDATE statements.
Therefore there's no way to deterministically set the scan method for UPDATE query.
I guess I have to rely on MySQL's heuristics on deciding which scan method is faster based on table size, etc. Not ideal, because I don't know what's gonna be the performance profile for that query anymore, but I hope it will at least be "Index Range Scan" and nothing worse...
Reference: How to force mysql UPDATE query to use index? How to enable mysql engine to automatically use the index instead of forcing it?
https://dba.stackexchange.com/a/153323/146991
The index hint is a red herring. I think it is because of internal differences between SELECT and UPDATE, especially when it comes to planning the query.
Suggest you file a bug.
I think it is not really doing a "range". You can get some confidence in this by doing:
FLUSH STATUS;
UPDATE ... ;
SHOW SESSION STATUS LIKE 'Handler%';
(I have checked a variety of versions; nothing hints that more than 1 row is being hit other than the dubious "range".)
In an application, sometimes queries are slow, and I "explain" them after the fact (if they are slow) and log them, so I can improve the application over time.
However, if I run an "explain " after, row_count() no longer reflects the number of rows affected by the original query, which I don't want. Is there a way to run an explain query (or perhaps any query), and not change row_count()?
Note: What I am currently doing is to open a separate link to the database, and explain using that link. That works, but I am unable to explain queries using temporary tables in that way. I am looking for a different solution that will preserve row_count() and work with temporary tables.
Capture row_count() into a variable, if you need it later. You should probably be doing this anyway, since the scope of validity of this value is very limited.
The value is tied to the specific connection, and is reset with each query you execute... and EXPLAIN ... is a query.
There's not a way to change this behavior.
Rearrange your code...
SELECT ...
get ROW_COUNT ...
EXPLAIN SELECT ...
Note also that EXPLAIN's "Row" column is an approximation; it will rarely match ROW_COUNT().
If I set set optimizer_switch='block_nested_loop=off' as suggested here, can i get 100% certainty the same result for option on and off ?
I want to change this option to off, because it increases query performance in my case from 56s to 1s.
What are the pros and cons for this optimizer switch, is it safe?
Yes, it is safe. The optimizer_switch tells MySql how to search for the answer to the query. Regardless of how optimizer_switch is set, it will generate the same result for your query (unless there are bugs in MySql).
The only disadvantage to using set optimizer_switch='block_nested_loop=off' is that other queries might become slower, so you might want to set it back to on after executing your query.
I have been learning query optimization, increase query performance and all but in general if we create a query how can we know if this is a wise query.
I know we can see the execution time below, But this time will not give a clear indication without a good amount of data. And usually, when we create a new query we don't have much data to check.
I have learned about clauses and commands performance. But is there is anything by which we can check the performance of the query? Performance here is not execution time, it means that whether a query is "ok" or not, without data dependency.
As we cannot create that much data that would be in live database.
General performance of a query can be checked using the EXPLAIN command in MySQL. See https://dev.mysql.com/doc/refman/5.7/en/using-explain.html
It shows you how MySQL engine plans to execute the query and allows you to do some basic sanity checks i.e. if the engine will use keys and indexes to execute the query, see how MySQL will execute the joins (i.e. if foreign keys aren't missing) and many more.
You can find some general tips about how to use EXPLAIN for optimizing queries here (along with some nice samples): http://www.sitepoint.com/using-explain-to-write-better-mysql-queries/
As mentioned above, Right query is always data-dependent. Up to some level you can use the below methods to check the performance
You can use Explain to understand the Query Execution Plan and that may help you to correct some stuffs. For more info :
Refer Documentation Optimizing Queries with EXPLAIN
You can use Query Analyzer. Refer MySQL Query Analyzer
I like to throw my cookbook at Newbies because they often do not understand how important INDEXes are, or don't know some of the subtleties.
When experimenting with multiple choices of query/schema, I like to use
FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler%';
That counts low level actions, such as "read next record". It essentially eliminates caching issues, disk speed, etc, and is very reproducible. Often there is a counter in that output (or multiple counters) that match the number of rows in the table (sometimes +/-1) -- that tells me there are table scan(s). This is usually not as good as if some INDEX were being used. If the query has a LIMIT, that value may show up in some Handler.
A really bad query, such as a CROSS JOIN, would show a value of N*M, where N and M are the row counts for the two tables.
I used the Handler technique to 'prove' that virtually all published "get me a random row" techniques require a table scan. Then I could experiment with small tables and Handlers to come up with a list of faster random routines.
Another tip when timing... Turn off the Query_cache (or use SELECT SQL_NO_CACHE).
Ive been using PHP and MySQL for a while now and I still don't understand when I should add Indexes to colums in my MySQL tables to increase performance. Are there any simple resources to help explain this to me?
In short, anything that will appear in a WHERE or ON clause should probably have an index on it. As well, you can use MySQL's EXPLAIN command to see how it actually executes the query which can point out where indexes are needed.