prepared_statementの投げ方とMySQLからの確認の仕方
以前書いたような気がするのだが、検索してもなかったので書く。 Prepared statementを使ってcom_stmt_prepareが流れるか見てみる。
結論:流れた。
実際のサービスでは使われないらしいがどうなのだろうか?prepareしてidとパラメータ指定の2往復になってしまうため、1 session中に複数回同じstatementを投げない限りパフォーマンスが落ちるというのはわかるが、、、
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "log" "time" ) func generalQuery() { db, error := sql.Open("mysql", "root:root@tcp(127.0.0.1:13306)/sakila") if error != nil { log.Fatal(error) } rows, err := db.Query("SELECT film_id FROM film limit 3") if err != nil { log.Fatal(err) } var id int var c1 int for rows.Next() { err = rows.Scan(&id) if err != nil { log.Fatal(err) } fmt.Println(id, c1) } } func preparedStatements() { db, error := sql.Open("mysql", "root:root@tcp(127.0.0.1:13306)/sakila") if error != nil { log.Fatal(error) } stmtSelect, err := db.Prepare("SELECT film_id FROM film WHERE film_id = ?") if err != nil { panic(err.Error()) // proper error handling instead of panic in your app } defer stmtSelect.Close() time.Sleep(3 * time.Second) var squareNum int // Query id = 1 err = stmtSelect.QueryRow(1).Scan(&squareNum) if err != nil { panic(err.Error()) // proper error handling instead of panic in your app } fmt.Println(squareNum) // Query id = 2 err = stmtSelect.QueryRow(2).Scan(&squareNum) if err != nil { panic(err.Error()) // proper error handling instead of panic in your app } fmt.Println(squareNum) } func main() { generalQuery() preparedStatements() }
ついでにMySQL側でPreparedされたクエリを取得するにはperformance_schema.prepared_statements_instancesテーブルを参照する. 5.7.4で導入されたようなことが書いてあるので要確認.
https://mysqlserverteam.com/mysql-performance-schema-prepared-statements-instrumentation/
上記のコードでprepareされたクエリのサンプル
mysql> select * from prepared_statements_instances\G *************************** 1. row *************************** OBJECT_INSTANCE_BEGIN: 140545020190976 STATEMENT_ID: 1 STATEMENT_NAME: NULL SQL_TEXT: SELECT film_id FROM film WHERE film_id = ? OWNER_THREAD_ID: 42 OWNER_EVENT_ID: 1 OWNER_OBJECT_TYPE: NULL OWNER_OBJECT_SCHEMA: NULL OWNER_OBJECT_NAME: NULL TIMER_PREPARE: 170553000 COUNT_REPREPARE: 0 COUNT_EXECUTE: 0 SUM_TIMER_EXECUTE: 0 MIN_TIMER_EXECUTE: 0 AVG_TIMER_EXECUTE: 0 MAX_TIMER_EXECUTE: 0 SUM_LOCK_TIME: 0 SUM_ERRORS: 0 SUM_WARNINGS: 0 SUM_ROWS_AFFECTED: 0 SUM_ROWS_SENT: 0 SUM_ROWS_EXAMINED: 0 SUM_CREATED_TMP_DISK_TABLES: 0 SUM_CREATED_TMP_TABLES: 0 SUM_SELECT_FULL_JOIN: 0 SUM_SELECT_FULL_RANGE_JOIN: 0 SUM_SELECT_RANGE: 0 SUM_SELECT_RANGE_CHECK: 0 SUM_SELECT_SCAN: 0 SUM_SORT_MERGE_PASSES: 0 SUM_SORT_RANGE: 0 SUM_SORT_ROWS: 0 SUM_SORT_SCAN: 0 SUM_NO_INDEX_USED: 0 SUM_NO_GOOD_INDEX_USED: 0 1 row in set (0.00 sec)