From c4e357af9a65cc3e711444cc47281fb86c0ce10b Mon Sep 17 00:00:00 2001 From: Philip Olson Date: Thu, 22 Mar 2012 23:50:17 +0000 Subject: [PATCH] CS and WS git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@324476 c90b9560-bf6c-de11-be94-00142212c4b1 --- reference/mysqlnd_qc/constants.xml | 23 +- reference/mysqlnd_qc/ini.xml | 3 +- reference/mysqlnd_qc/quickstart.xml | 357 ++++++++++++++-------------- 3 files changed, 187 insertions(+), 196 deletions(-) diff --git a/reference/mysqlnd_qc/constants.xml b/reference/mysqlnd_qc/constants.xml index cd918ef7c3..1b1f3a94b7 100644 --- a/reference/mysqlnd_qc/constants.xml +++ b/reference/mysqlnd_qc/constants.xml @@ -58,21 +58,18 @@ MYSQLND_QC_TTL_SWITCH: qc_ttl= MYSQLND_QC_ENABLE_SWITCH - ( - string) + (string) - SQL hint used to enable caching of a query. + SQL hint used to enable caching of a query. - MYSQLND_QC_DISABLE_SWITCH - ( - string) + (string) @@ -84,8 +81,7 @@ MYSQLND_QC_TTL_SWITCH: qc_ttl= MYSQLND_QC_TTL_SWITCH - ( - string) + (string) @@ -96,8 +92,7 @@ MYSQLND_QC_TTL_SWITCH: qc_ttl= MYSQLND_QC_SERVER_ID_SWITCH - ( - string) + (string) @@ -129,7 +124,6 @@ MYSQLND_QC_TTL_SWITCH: qc_ttl= - mysqlnd_qc_set_cache_condition related @@ -167,13 +161,12 @@ $pdo_mysql->query("SELECT id, title FROM news"); MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN - ( - int) + (int) - Used as a parameter of mysqlnd_qc_set_cache_condition - to set conditions for schema based automatic caching. + Used as a parameter of mysqlnd_qc_set_cache_condition + to set conditions for schema based automatic caching. diff --git a/reference/mysqlnd_qc/ini.xml b/reference/mysqlnd_qc/ini.xml index 665e2ed48e..4e64bca159 100644 --- a/reference/mysqlnd_qc/ini.xml +++ b/reference/mysqlnd_qc/ini.xml @@ -423,8 +423,7 @@ sqlite storage handler: data file. Any setting - but - :memory: may be of little practical value. + but :memory: may be of little practical value. diff --git a/reference/mysqlnd_qc/quickstart.xml b/reference/mysqlnd_qc/quickstart.xml index 04feffa82d..b20cacf529 100644 --- a/reference/mysqlnd_qc/quickstart.xml +++ b/reference/mysqlnd_qc/quickstart.xml @@ -42,7 +42,7 @@ a comparison with proxy based solutions. - Transparent to use + Transparent to use At PHP run time PECL/mysqlnd_qc can proxy queries send from PHP @@ -61,7 +61,7 @@ PHP MySQL extensions. - Flexible storage: various storage handler + Flexible storage: various storage handler Various storage handler are supported to offer different scopes for cache @@ -105,8 +105,8 @@ However, it is recommended to pick one storage handler and use it for all cache entries. - Built-in slam defense to avoid overloading - + Built-in slam defense to avoid overloading + To avoid overload situations the cache plugin has a built-in slam defense mechanism. If a popular cache entries expires many clients using the cache entries will try @@ -124,8 +124,8 @@ situation. - Unique approach to caching - + Unique approach to caching + PECL/mysqlnd_qc has a unique approach to caching result sets that is superior to application based cache solutions. Application based solutions first fetch @@ -183,7 +183,7 @@ mysqlnd_qc.enable_qc=1 - User supplied callbacks to decide on a per query basis, for example, using mysqlnd_qc_is_select + User supplied callbacks to decide on a per query basis, for example, using mysqlnd_qc_is_select @@ -221,7 +221,7 @@ mysqlnd_qc.enable_qc=1 - + not eligible for caching and not cached: INSERT INTO test(id) VALUES (1) @@ -267,21 +267,25 @@ $mysqli->query("INSERT INTO test(id) VALUES (1), (2)"); /* Will be cached because of the SQL hint */ $start = microtime(true); -$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1"); +$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1"); + var_dump($res->fetch_assoc()); $res->free(); + printf("Total time uncached query: %.6fs\n", microtime(true) - $start); /* Cache hit */ $start = microtime(true); -$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1"); +$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1"); + var_dump($res->fetch_assoc()); $res->free(); + printf("Total time cached query: %.6fs\n", microtime(true) - $start); ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; free(); ?> ]]> - &examples.outputs; + &examples.outputs; query("INSERT INTO test(id) VALUES (1)"); for ($i = 0; $i < 3; $i++) { - $start = microtime(true); + $start = microtime(true); - /* Note: statement will not be cached because of NOW() use */ - $res = $mysqli->query("SELECT id, NOW() AS _time FROM test"); - $row = $res->fetch_assoc(); + /* Note: statement will not be cached because of NOW() use */ + $res = $mysqli->query("SELECT id, NOW() AS _time FROM test"); + $row = $res->fetch_assoc(); - /* dump results */ - var_dump($row); + /* dump results */ + var_dump($row); - printf("Total time: %.6fs\n", microtime(true) - $start); + printf("Total time: %.6fs\n", microtime(true) - $start); - /* pause one second */ - sleep(1); + /* pause one second */ + sleep(1); } ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; query("INSERT INTO test(id) VALUES (1)"); for ($i = 0; $i < 3; $i++) { - $start = microtime(true); + $start = microtime(true); - /* Note: statement will not be cached because of NOW() use */ - $res = $mysqli->query("SELECT id, NOW() AS _time FROM test"); - $row = $res->fetch_assoc(); + /* Note: statement will not be cached because of NOW() use */ + $res = $mysqli->query("SELECT id, NOW() AS _time FROM test"); + $row = $res->fetch_assoc(); - /* dump results */ - var_dump($row); + /* dump results */ + var_dump($row); - printf("Total time: %.6fs\n", microtime(true) - $start); + printf("Total time: %.6fs\n", microtime(true) - $start); - /* pause one second */ - sleep(1); + /* pause one second */ + sleep(1); } ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; query("CREATE TABLE test(id VARCHAR(255))"); for ($i = 0; $i < 7; $i++) { - /* update DB row */ - if (!$mysqli->query("DELETE FROM test") || - !$mysqli->query("INSERT INTO test(id) VALUES (NOW())")) - /* Of course, a real-life script should do better error handling */ - die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error)); + /* update DB row */ + if (!$mysqli->query("DELETE FROM test") || + !$mysqli->query("INSERT INTO test(id) VALUES (NOW())")) + /* Of course, a real-life script should do better error handling */ + die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error)); - /* select latest row but cache results */ - $query = "/*" . MYSQLND_QC_ENABLE_SWITCH . "*/"; - $query .= "SELECT id AS _time FROM test"; - if (!($res = $mysqli->query($query)) || - !($row = $res->fetch_assoc())) - { - printf("[%d] %s\n", $mysqli->errno, $mysqli->error); - } - $res->free(); - printf("Wall time %s - DB row time %s\n", date("H:i:s"), $row['_time']); + /* select latest row but cache results */ + $query = "/*" . MYSQLND_QC_ENABLE_SWITCH . "*/"; + $query .= "SELECT id AS _time FROM test"; + if (!($res = $mysqli->query($query)) || + !($row = $res->fetch_assoc())) + { + printf("[%d] %s\n", $mysqli->errno, $mysqli->error); + } + $res->free(); + printf("Wall time %s - DB row time %s\n", date("H:i:s"), $row['_time']); - /* pause one second */ - sleep(1); + /* pause one second */ + sleep(1); } ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; query("INSERT INTO test(id) VALUES (1), (2)"); printf("Default TTL\t: %d seconds\n", ini_get("mysqlnd_qc.ttl")); /* Will be cached for 2 seconds */ -$sql = sprintf("/*%s*//*%s%d*/SELECT id FROM test WHERE id = 1", - MYSQLND_QC_ENABLE_SWITCH, - MYSQLND_QC_TTL_SWITCH, - 2); +$sql = sprintf("/*%s*//*%s%d*/SELECT id FROM test WHERE id = 1", MYSQLND_QC_ENABLE_SWITCH, MYSQLND_QC_TTL_SWITCH, 2); $res = $mysqli->query($sql); + var_dump($res->fetch_assoc()); $res->free(); @@ -671,7 +673,7 @@ printf("Script runtime\t: %d seconds\n", microtime(true) - $start); ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; - @@ -731,22 +732,22 @@ mysqlnd_qc.collect_statistics=1 true, - /* 3 - use TTL = 3 seconds */ - "@SELECT\s+.*\s+FROM\s+news@ismU" => 3 - ); + static $patterns = array( + /* true - use default from mysqlnd_qc.ttl */ + "@SELECT\s+.*\s+FROM\s+test@ismU" => true, + /* 3 - use TTL = 3 seconds */ + "@SELECT\s+.*\s+FROM\s+news@ismU" => 3 + ); - /* check if query does match pattern */ - foreach ($patterns as $pattern => $ttl) { - if (preg_match($pattern, $query)) { - printf("is_select(%45s): cache\n", $query); - return $ttl; + /* check if query does match pattern */ + foreach ($patterns as $pattern => $ttl) { + if (preg_match($pattern, $query)) { + printf("is_select(%45s): cache\n", $query); + return $ttl; + } } - } - printf("is_select(%45s): do not cache\n", $query); - return false; + printf("is_select(%45s): do not cache\n", $query); + return false; } /* install callback */ mysqlnd_qc_set_is_select("is_select"); @@ -894,8 +895,8 @@ $mysqli = new mysqli("host", "user", "password", "schema", "port", "socket"); /* dummy queries to fill the query trace */ for ($i = 0; $i < 2; $i++) { - $res = $mysqli->query("SELECT 1 AS _one FROM DUAL"); - $res->free(); + $res = $mysqli->query("SELECT 1 AS _one FROM DUAL"); + $res->free(); } /* dump trace */ @@ -903,7 +904,7 @@ var_dump(mysqlnd_qc_get_query_trace_log()); ?> ]]> - &examples.outputs; + &examples.outputs; query("INSERT INTO test(id) VALUES (1), (2), (3)"); /* dummy queries to fill the query trace */ for ($i = 0; $i < 3; $i++) { - $res = $mysqli->query("SELECT id FROM test WHERE id = " . $mysqli->real_escape_string($i)); - $res->free(); + $res = $mysqli->query("SELECT id FROM test WHERE id = " . $mysqli->real_escape_string($i)); + $res->free(); } $trace = mysqlnd_qc_get_query_trace_log(); $summary = array(); foreach ($trace as $entry) { - if (!isset($summary[$entry['query']])) { - $summary[$entry['query']] = array( - "executions" => 1, - "time" => $entry['run_time'] + $entry['store_time'], - ); - } else { - $summary[$entry['query']]['executions']++; - $summary[$entry['query']]['time'] += $entry['run_time'] + $entry['store_time']; - } + if (!isset($summary[$entry['query']])) { + $summary[$entry['query']] = array( + "executions" => 1, + "time" => $entry['run_time'] + $entry['store_time'], + ); + } else { + $summary[$entry['query']]['executions']++; + $summary[$entry['query']]['time'] += $entry['run_time'] + $entry['store_time']; + } } + foreach ($summary as $query => $details) { - printf("%45s: %5dms (%dx)\n", - $query, $details['time'], $details['executions']); + printf("%45s: %5dms (%dx)\n", + $query, $details['time'], $details['executions']); } ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; query("INSERT INTO test(id) VALUES (1), (2), (3)"); /* dummy queries */ for ($i = 1; $i <= 4; $i++) { - $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", - MYSQLND_QC_ENABLE_SWITCH, - $i % 2); - $res = $mysqli->query($query); - $res->free(); + $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", MYSQLND_QC_ENABLE_SWITCH, $i % 2); + $res = $mysqli->query($query); + + $res->free(); } var_dump(mysqlnd_qc_get_core_stats()); ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; query("INSERT INTO test(id) VALUES (1), (2), (3)"); /* dummy queries to fill the query trace */ for ($i = 1; $i <= 4; $i++) { - $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", - MYSQLND_QC_ENABLE_SWITCH, - $i % 2); - $res = $mysqli->query($query); - $res->free(); + $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", MYSQLND_QC_ENABLE_SWITCH, $i % 2); + $res = $mysqli->query($query); + + $res->free(); } + var_dump(mysqlnd_qc_get_cache_info()); ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; query("INSERT INTO test(id) VALUES (1), (2), (3)"); /* dummy queries to fill the query trace */ for ($i = 1; $i <= 4; $i++) { - $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", - MYSQLND_QC_ENABLE_SWITCH, - $i % 2); - $res = $mysqli->query($query); - $res->free(); + $query = sprintf("/*%s*/SELECT id FROM test WHERE id = %d", MYSQLND_QC_ENABLE_SWITCH, $i % 2); + $res = $mysqli->query($query); + + $res->free(); } + var_dump(mysqlnd_qc_get_normalized_query_trace_log()); ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; $data, - "row_count" => $row_count, - "valid_until" => time() + $ttl, - "hits" => 0, - "run_time" => $run_time, - "store_time" => $store_time, - "cached_run_times" => array(), - "cached_store_times" => array(), - ); + $__cache[$key] = array( + "data" => $data, + "row_count" => $row_count, + "valid_until" => time() + $ttl, + "hits" => 0, + "run_time" => $run_time, + "store_time" => $store_time, + "cached_run_times" => array(), + "cached_store_times" => array(), + ); - return TRUE; + return TRUE; } function query_is_select($query) { - printf("\t%s('%s'): ", __FUNCTION__, $query); + printf("\t%s('%s'): ", __FUNCTION__, $query); - $ret = FALSE; - if (stristr($query, "SELECT") !== FALSE) { - /* cache for 5 seconds */ - $ret = 5; - } + $ret = FALSE; + if (stristr($query, "SELECT") !== FALSE) { + /* cache for 5 seconds */ + $ret = 5; + } - printf("%s\n", (FALSE === $ret) ? "FALSE" : $ret); - return $ret; + printf("%s\n", (FALSE === $ret) ? "FALSE" : $ret); + return $ret; } function update_query_run_time_stats($key, $run_time, $store_time) { - global $__cache; - printf("\t%s(%d)\n", __FUNCTION__, func_num_args()); + global $__cache; + printf("\t%s(%d)\n", __FUNCTION__, func_num_args()); - if (isset($__cache[$key])) { - $__cache[$key]['hits']++; - $__cache[$key]["cached_run_times"][] = $run_time; - $__cache[$key]["cached_store_times"][] = $store_time; - } + if (isset($__cache[$key])) { + $__cache[$key]['hits']++; + $__cache[$key]["cached_run_times"][] = $run_time; + $__cache[$key]["cached_store_times"][] = $store_time; + } } function get_stats($key = NULL) { - global $__cache; - printf("\t%s(%d)\n", __FUNCTION__, func_num_args()); + global $__cache; + printf("\t%s(%d)\n", __FUNCTION__, func_num_args()); - if ($key && isset($__cache[$key])) { - $stats = $__cache[$key]; - } else { - $stats = array(); - foreach ($__cache as $key => $details) { - $stats[$key] = array( - 'hits' => $details['hits'], - 'bytes' => strlen($details['data']), - 'uncached_run_time' => $details['run_time'], - 'cached_run_time' => (count($details['cached_run_times'])) - ? array_sum($details['cached_run_times']) / count($details['cached_run_times']) - : 0, - ); + if ($key && isset($__cache[$key])) { + $stats = $__cache[$key]; + } else { + $stats = array(); + foreach ($__cache as $key => $details) { + $stats[$key] = array( + 'hits' => $details['hits'], + 'bytes' => strlen($details['data']), + 'uncached_run_time' => $details['run_time'], + 'cached_run_time' => (count($details['cached_run_times'])) + ? array_sum($details['cached_run_times']) / count($details['cached_run_times']) + : 0, + ); + } } - } - return $stats; + return $stats; } function clear_cache() { - global $__cache; - printf("\t%s(%d)\n", __FUNCTION__, func_num_args()); + global $__cache; + printf("\t%s(%d)\n", __FUNCTION__, func_num_args()); - $__cache = array(); - return TRUE; + $__cache = array(); + return TRUE; } /* Install procedural user-defined storage handler */ if (!mysqlnd_qc_set_user_handlers("get_hash", "find_query_in_cache", - "return_to_cache", "add_query_to_cache_if_not_exists", - "query_is_select", "update_query_run_time_stats", - "get_stats", "clear_cache")) { - printf("Failed to install user-defined storage handler\n"); + "return_to_cache", "add_query_to_cache_if_not_exists", + "query_is_select", "update_query_run_time_stats", "get_stats", "clear_cache")) { + + printf("Failed to install user-defined storage handler\n"); } @@ -1629,7 +1630,7 @@ $res->free(); ?> ]]> - &examples.outputs.similar; + &examples.outputs.similar; - -