In my 20+ years as a MySQL DBA, working for companies with only 2-3 MySQL servers, all the way up to 10,000+ servers handling millions of QPS, I can emphatically state that prepared statements are NOT the de facto standard in any way. They may be standard for you, but in general, they are not used.
The main reason they are not used is because prepared statements donât gain you anything other than overhead. If you prepare, then bind, then execute a single SELECT statement only once, youâve gained nothing, and added a proportionality large amount of bloat, compared to simply executing the SELECT directly.
If you were to execute that same SELECT 10,000+ times in a row with varying WHERE predicate changes, then yes, you might squeak out a bit of efficiency in terms of network data/round-trip.
Prepared statements donât change the way the optimizer works. Turn on optimizer tracing, then EXECUTE a prepared statement. View the trace. EXECUTE again with different statement parameters, view this trace, and youâll see the optimizer potentially choosing a different execution path.
Prepared statements also do not protect 100% against SQL injection. In some cases, force-casting strings to integer can help, but when you bind strings, you can still technically inject malicious SQL. We have several slides in our MySQL Developers training course where we show this.
Prepared statements are deallocated when the connection closes. Most applications connect to mysql, execute queries, then disconnect, as this is considered best-practice. Thus, by using prepared statements, youâre just wasting memory/cpu/network over, and over by re-preparing the same statement on each connection.
Iâm not telling you to stop using them; you do you. What I am saying is that they are absolutely not standard by any means, and rarely offer a performance benefit.
Regarding PMM QAN, the problem is on the MySQL side. PMM QAN scrapes performance_schema.events_statements_history for metrics. Prepared statements are not added to this table by MySQL. PMM is doing all that it can, but if MySQL does not provide the data, thereâs nothing we can do about it. I found two open, and verified bugs on this issue dating back to 5.6.