将传输中的 PHP PDO 网络传输数据最小化到 MySQL
Minimise PHP PDO network transfer data in transit to MySQL
假设目标 table 是这样的:
CREATE TABLE mysql_mytable (
myint INT,
mytinyint TINYINT,
mydecimal DECIMAL(10,2),
mydatetime DATETIME, mydate DATE
)
以及以下带有多个测试用例的代码:
$mysql_pdo = new PDO("mysql:...", ..., [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
foreach ([
'myint' => [
'a' => [PDO::PARAM_STR, "1048575"],
'b' => [PDO::PARAM_STR, 1048575],//same as previous?
'c' => [PDO::PARAM_STR, dechex(1048575), 'UNHEX(?)'],//"FFFFF"
'e' => [PDO::PARAM_INT, 1048575],//fewest as 4 byte int?
'f' => [PDO::PARAM_INT, "1048575"],//same as previous?
],
'mytinyint' => [
'a' => [PDO::PARAM_STR, "255"],
'b' => [PDO::PARAM_STR, 255],//same as previous?
'c' => [PDO::PARAM_STR, dechex(255), 'UNHEX(?)'],//"FF" fewest bytes as VARCHAR?
'e' => [PDO::PARAM_INT, 255],
'f' => [PDO::PARAM_INT, "255"],//same as previous?
],
'mydecimal' => [//PDO::PARAM_INT cannot be used correctly for decimals?
'a' => [PDO::PARAM_STR, "32000000.00"],
'b' => [PDO::PARAM_STR, "3.2e7"],//fewest bytes as VARCHAR?
],
'mydatetime' => [
'a' => [PDO::PARAM_STR, "2021-05-10 09:09:39"],
'c' => [PDO::PARAM_STR, strtotime("2021-05-10 09:09:39")],
'd' => [PDO::PARAM_INT, strtotime("2021-05-10 09:09:39")],//fewest as 4 byte int?
],
'mydate' => [
'a' => [PDO::PARAM_STR, "2021-05-10"],
'c' => [PDO::PARAM_STR, strtotime("2021-05-10")],
'd' => [PDO::PARAM_INT, strtotime("2021-05-10")],//fewest as 4 byte int?
]
] as $col => $tests) {
foreach ($tests as $case_label => $test) {
list($type, $value) = $test;
$mark = isset($test[2]) ? $test[2] : '?';
$stmt = $mysql_pdo->prepare('INSERT INTO mysql_mytable ({$col}) VALUES ({$mark})');
$stmt->bindValue(1, $value, $type);
$stmt->execute();
}
}
我花了很多时间优化 table 上使用的磁盘 space - 但是有大量数据流向非本地 MySQL 实例。有很多列和很多行……上面只是为了显示其中的某些组和选项……这真的是导入——是的,我正在考虑使插入在禁用键检查、索引等方面变得高效.我重复这是带有示例代码的示例,我正在寻求帮助以最大程度地减少发送到远程 MySQL 实例的数据量...是的,这是大量数据,是的,连接速度足够慢并且过程时间非常重要,因此很重要。
对于 column/test 组,哪个会导致通过网络传输到 MySQL 数据库的字节数最少?
是否有任何方法可以限制以不同方式使用 PDO
或根本不使用 PDO
的数据?
无论是十进制还是十六进制,整数都比字符串中的等效值更紧凑。
十进制值1048575需要7个字符,十六进制值FFFFF需要5个字符。而整数仅使用 4 个字节。
还要考虑是否启用了 PDO::ATTR_EMULATE_PREPARES
。这将破坏整数参数的使用,因为字符串值将被插入到查询字符串中,而不是作为实际参数单独发送。
就我自己而言,我不关心简单数据类型的网络传输。网络足够快,与查询执行时间相比,传输时间可以忽略不计。也许如果您正在传输大 BLOB/TEXT 内容,或者如果您正在批量加载数百万行,但通常单个整数的 4 字节和 5-8 字节之间的差异不会解决任何性能瓶颈.
假设目标 table 是这样的:
CREATE TABLE mysql_mytable (
myint INT,
mytinyint TINYINT,
mydecimal DECIMAL(10,2),
mydatetime DATETIME, mydate DATE
)
以及以下带有多个测试用例的代码:
$mysql_pdo = new PDO("mysql:...", ..., [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
foreach ([
'myint' => [
'a' => [PDO::PARAM_STR, "1048575"],
'b' => [PDO::PARAM_STR, 1048575],//same as previous?
'c' => [PDO::PARAM_STR, dechex(1048575), 'UNHEX(?)'],//"FFFFF"
'e' => [PDO::PARAM_INT, 1048575],//fewest as 4 byte int?
'f' => [PDO::PARAM_INT, "1048575"],//same as previous?
],
'mytinyint' => [
'a' => [PDO::PARAM_STR, "255"],
'b' => [PDO::PARAM_STR, 255],//same as previous?
'c' => [PDO::PARAM_STR, dechex(255), 'UNHEX(?)'],//"FF" fewest bytes as VARCHAR?
'e' => [PDO::PARAM_INT, 255],
'f' => [PDO::PARAM_INT, "255"],//same as previous?
],
'mydecimal' => [//PDO::PARAM_INT cannot be used correctly for decimals?
'a' => [PDO::PARAM_STR, "32000000.00"],
'b' => [PDO::PARAM_STR, "3.2e7"],//fewest bytes as VARCHAR?
],
'mydatetime' => [
'a' => [PDO::PARAM_STR, "2021-05-10 09:09:39"],
'c' => [PDO::PARAM_STR, strtotime("2021-05-10 09:09:39")],
'd' => [PDO::PARAM_INT, strtotime("2021-05-10 09:09:39")],//fewest as 4 byte int?
],
'mydate' => [
'a' => [PDO::PARAM_STR, "2021-05-10"],
'c' => [PDO::PARAM_STR, strtotime("2021-05-10")],
'd' => [PDO::PARAM_INT, strtotime("2021-05-10")],//fewest as 4 byte int?
]
] as $col => $tests) {
foreach ($tests as $case_label => $test) {
list($type, $value) = $test;
$mark = isset($test[2]) ? $test[2] : '?';
$stmt = $mysql_pdo->prepare('INSERT INTO mysql_mytable ({$col}) VALUES ({$mark})');
$stmt->bindValue(1, $value, $type);
$stmt->execute();
}
}
我花了很多时间优化 table 上使用的磁盘 space - 但是有大量数据流向非本地 MySQL 实例。有很多列和很多行……上面只是为了显示其中的某些组和选项……这真的是导入——是的,我正在考虑使插入在禁用键检查、索引等方面变得高效.我重复这是带有示例代码的示例,我正在寻求帮助以最大程度地减少发送到远程 MySQL 实例的数据量...是的,这是大量数据,是的,连接速度足够慢并且过程时间非常重要,因此很重要。
对于 column/test 组,哪个会导致通过网络传输到 MySQL 数据库的字节数最少?
是否有任何方法可以限制以不同方式使用 PDO
或根本不使用 PDO
的数据?
无论是十进制还是十六进制,整数都比字符串中的等效值更紧凑。
十进制值1048575需要7个字符,十六进制值FFFFF需要5个字符。而整数仅使用 4 个字节。
还要考虑是否启用了 PDO::ATTR_EMULATE_PREPARES
。这将破坏整数参数的使用,因为字符串值将被插入到查询字符串中,而不是作为实际参数单独发送。
就我自己而言,我不关心简单数据类型的网络传输。网络足够快,与查询执行时间相比,传输时间可以忽略不计。也许如果您正在传输大 BLOB/TEXT 内容,或者如果您正在批量加载数百万行,但通常单个整数的 4 字节和 5-8 字节之间的差异不会解决任何性能瓶颈.