applied review comments

This commit is contained in:
v-kaywon 2017-08-22 16:15:33 -07:00
parent 459840e4b2
commit 5990f6e7b6
22 changed files with 416 additions and 217 deletions

View file

@ -28,7 +28,7 @@ PHPBench is used to run the benchmarks. Visit http://phpbench.readthedocs.io/en/
##### 4. Execute run-perf_tests.py. ##### 4. Execute run-perf_tests.py.
### Windows ### Windows
py.exe run-perf_tests.py -platform <PLATFORM> > tee run-perf_output.txt py.exe run-perf_tests.py -platform <PLATFORM>
### Linux and Mac ### Linux and Mac
On Linux and Mac, the script must be executed with `sudo python3` because to enable pooling it needs to modify odbcinst.ini system file. As an improvement, the location of the odbcinst.ini file can be changed so that, sudo is not requiered. On Linux and Mac, the script must be executed with `sudo python3` because to enable pooling it needs to modify odbcinst.ini system file. As an improvement, the location of the odbcinst.ini file can be changed so that, sudo is not requiered.
@ -36,4 +36,4 @@ On Linux and Mac, the script must be executed with `sudo python3` because to ena
`-platform` - The platform that the tests are ran on. Must be one of the following: Windows10, WindowsServer2016, WindowsServer2012, Ubuntu16, RedHat7, Sierra. `-platform` - The platform that the tests are ran on. Must be one of the following: Windows10, WindowsServer2016, WindowsServer2012, Ubuntu16, RedHat7, Sierra.
`-php-driver` (optional) - The driver that the tests are ran on. Must be one of the following: sqlsrv, pdo_sqlsrv, or both. Default is both. `-php-driver` (optional) - The driver that the tests are ran on. Must be one of the following: sqlsrv, pdo_sqlsrv, or both. Default is both.
`-test-only` (optional) - The test to run. Must be the file name (not including path) of one test or 'all'. Default is 'all'. If one test is specified, must also specify the -php-driver option to sqlsrv or pdo_sqlsrv. `-testname` (optional) - The test to run. Must be the file name (not including path) of one test or 'all'. Default is 'all'. If one test is specified, must also specify the -php-driver option to sqlsrv or pdo_sqlsrv.

View file

@ -1,14 +1,15 @@
<?php <?php
use PDOSqlsrvPerfTest\PDOSqlsrvUtil; use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
/** include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
* @Iterations(1000)
*/ class PDOConnectionBench extends CRUDBaseBenchmark
class PDOConnectionBench{ {
/* /*
* Opens a connection and closes it immediately * Opens a connection and closes it immediately
*/ */
public function benchConnectAndDisconnect(){ public function benchConnectAndDisconnect()
{
$conn = PDOSqlsrvUtil::connect(); $conn = PDOSqlsrvUtil::connect();
PDOSqlsrvUtil::disconnect( $conn ); PDOSqlsrvUtil::disconnect( $conn );
} }

View file

@ -1,22 +1,25 @@
<?php <?php
use PDOSqlsrvPerfTest\PDOSqlsrvUtil; use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect"}) * @BeforeMethods({"connect"})
* @AfterMethods({"disconnect"}) * @AfterMethods({"disconnect"})
*/ */
class PDOCreateDbTableProcBench{ class PDOCreateDbTableProcBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
/* /*
* Each iteration creates a database, a table and a stored procedure in that database and drops the database at the end. * Each iteration creates a database, a table and a stored procedure in that database and drops the database at the end.
* Note that, execDirect function are used to execute all the queries. * Note that, execDirect function are used to execute all the queries.
*/ */
public function benchCreateDbTableProc(){ public function benchCreateDbTableProc()
{
$randomNum = rand(); $randomNum = rand();
$databaseName = "test_db_$randomNum"; $databaseName = "test_db_$randomNum";
$tableName = "test_table_$randomNum"; $tableName = "test_table_$randomNum";
@ -25,7 +28,8 @@ class PDOCreateDbTableProcBench{
PDOSqlsrvUtil::dropDatabase( $this->conn, $databaseName ); PDOSqlsrvUtil::dropDatabase( $this->conn, $databaseName );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -1,35 +1,42 @@
<?php <?php
use PDOSqlsrvPerfTest\PDOSqlsrvUtil; use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"})
* @AfterMethods({ "dropTable","disconnect"}) * @AfterMethods({ "dropTable","disconnect"})
*/ */
class PDODeleteBench{ class PDODeleteBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
private $insertValues; private $insertValues;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = PDOSqlsrvUtil::generateInsertValues(); $this->insertValues = PDOSqlsrvUtil::generateInsertValues();
} }
public function insertWithPrepare(){ public function insertWithPrepare()
for( $i=0; $i<100; $i++ ){ {
for( $i=0; $i<PDOSqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
} }
@ -37,17 +44,21 @@ class PDODeleteBench{
* Each iteration inserts 1000 rows into the table, benchDelete deletes top row from the table 1000 times. * Each iteration inserts 1000 rows into the table, benchDelete deletes top row from the table 1000 times.
* Note that, every delete calls prepare and execute APIs. * Note that, every delete calls prepare and execute APIs.
*/ */
public function benchDelete(){ public function benchDelete()
for( $i=0; $i<100; $i++ ){ {
for( $i=0; $i<PDOSqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
PDOSqlsrvUtil::deleteWithPrepare( $this->conn, $this->tableName ); PDOSqlsrvUtil::deleteWithPrepare( $this->conn, $this->tableName );
} }
} }
public function dropTable(){ public function dropTable()
{
PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }

View file

@ -1,33 +1,39 @@
<?php <?php
use PDOSqlsrvPerfTest\PDOSqlsrvUtil; use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"})
* @AfterMethods({"dropTable", "disconnect"}) * @AfterMethods({"dropTable", "disconnect"})
*/ */
class PDOFetchBench{ class PDOFetchBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
private $insertValues; private $insertValues;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = PDOSqlsrvUtil::generateInsertValues(); $this->insertValues = PDOSqlsrvUtil::generateInsertValues();
} }
public function insertWithPrepare(){ public function insertWithPrepare()
{
PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
@ -35,17 +41,21 @@ class PDOFetchBench{
* Each iteration inserts a row into the table, benchFetchWithPrepare() fetches that row 1000 times. * Each iteration inserts a row into the table, benchFetchWithPrepare() fetches that row 1000 times.
* Note that, every fetch calls prepare, execute and fetch APIs. * Note that, every fetch calls prepare, execute and fetch APIs.
*/ */
public function benchFetchWithPrepare(){ public function benchFetchWithPrepare()
for( $i=0; $i<100; $i++){ {
for( $i=0; $i<PDOSqlsrvUtil::$loopsPerCRUDIter; $i++)
{
PDOSqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName ); PDOSqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName );
} }
} }
public function dropTable(){ public function dropTable()
{
PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -6,27 +6,32 @@ use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
* @BeforeMethods({"connect", "setTableName" }) * @BeforeMethods({"connect", "setTableName" })
* @AfterMethods({ "disconnect"}) * @AfterMethods({ "disconnect"})
*/ */
class PDOFetchLargeBench{ class PDOFetchLargeBench
{
private $conn; private $conn;
private $tableName; private $tableName;
public function setTableName(){ public function setTableName()
{
//Assumes the table is already populated with data //Assumes the table is already populated with data
$this->tableName = "LargeDB.dbo.datatypes"; $this->tableName = "LargeDB.dbo.datatypes";
} }
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
/* /*
* Each iteration calls prepare, execute and fetch APIs to fetch the already populdated data * Each iteration calls prepare, execute and fetch APIs to fetch the already populdated data
*/ */
public function benchFetchWithPrepare(){ public function benchFetchWithPrepare()
{
PDOSqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName ); PDOSqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -1,46 +1,55 @@
<?php <?php
use PDOSqlsrvPerfTest\PDOSqlsrvUtil; use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues"})
* @AfterMethods({ "dropTable", "disconnect"}) * @AfterMethods({ "dropTable", "disconnect"})
*/ */
class PDOInsertBench{ class PDOInsertBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
private $insertValues; private $insertValues;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = PDOSqlsrvUtil::generateInsertValues(); $this->insertValues = PDOSqlsrvUtil::generateInsertValues();
} }
/** /**
* Each iteration inserts 1000 rows into the table. * Each iteration inserts 1000 rows into the table.
* Note that, every insertion calls prepare, bindParam and execute APIs. * Note that, every insertion calls prepare, bindParam and execute APIs.
*/ */
public function benchInsertWithPrepare(){ public function benchInsertWithPrepare()
for ( $i=0; $i<100; $i++){ {
for ( $i=0; $i<PDOSqlsrvUtil::$loopsPerCRUDIter; $i++)
{
PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
} }
public function dropTable(){ public function dropTable()
{
PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -6,21 +6,25 @@ use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
* @BeforeMethods({"connect"}) * @BeforeMethods({"connect"})
* @AfterMethods({"disconnect"}) * @AfterMethods({"disconnect"})
*/ */
class PDOSelectVersionBench{ class PDOSelectVersionBench
{
private $conn; private $conn;
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
/* /*
* Each iteration calls execDirect API to fetch @@Version * Each iteration calls execDirect API to fetch @@Version
*/ */
public function benchSelectVersion(){ public function benchSelectVersion()
{
$version = PDOSqlsrvUtil::selectVersion( $this->conn ); $version = PDOSqlsrvUtil::selectVersion( $this->conn );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -1,12 +1,13 @@
<?php <?php
use PDOSqlsrvPerfTest\PDOSqlsrvUtil; use PDOSqlsrvPerfTest\PDOSqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare", "generateUpdateValues", "generateUpdateParams"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare", "generateUpdateValues", "generateUpdateParams"})
* @AfterMethods({"dropTable", "disconnect"}) * @AfterMethods({"dropTable", "disconnect"})
*/ */
class PDOUpdateBench{ class PDOUpdateBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
@ -14,48 +15,59 @@ class PDOUpdateBench{
private $updateValues; private $updateValues;
private $updateParams; private $updateParams;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = PDOSqlsrvUtil::connect(); $this->conn = PDOSqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = PDOSqlsrvUtil::generateInsertValues(); $this->insertValues = PDOSqlsrvUtil::generateInsertValues();
} }
public function insertWithPrepare(){ public function insertWithPrepare()
{
PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); PDOSqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
public function generateUpdateValues(){ public function generateUpdateValues()
{
$this->updateValues = PDOSqlsrvUtil::generateUpdateValues(); $this->updateValues = PDOSqlsrvUtil::generateUpdateValues();
} }
public function generateUpdateParams(){ public function generateUpdateParams()
{
$this->updateParams = PDOSqlsrvUtil::generateUpdateParams(); $this->updateParams = PDOSqlsrvUtil::generateUpdateParams();
} }
/** /**
* Each iteration inserts a row into the table, updateWithPrepare() updates that row 1000 times. * Each iteration inserts a row into the table, updateWithPrepare() updates that row 1000 times.
* Note that, every update calls prepare, bindParam and execute APIs. * Note that, every update calls prepare, bindParam and execute APIs.
*/ */
public function benchUpdateWithPrepare(){ public function benchUpdateWithPrepare()
for( $i=0; $i<100; $i++ ){ {
for( $i=0; $i<PDOSqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
$stmt = PDOSqlsrvUtil::updateWithPrepare( $this->conn, $this->tableName, $this->updateValues, $this->updateParams ); $stmt = PDOSqlsrvUtil::updateWithPrepare( $this->conn, $this->tableName, $this->updateValues, $this->updateParams );
} }
} }
public function dropTable(){ public function dropTable()
{
PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName ); PDOSqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
PDOSqlsrvUtil::disconnect( $this->conn ); PDOSqlsrvUtil::disconnect( $this->conn );
} }

View file

@ -1,14 +1,15 @@
<?php <?php
use SqlsrvPerfTest\SqlsrvUtil; use SqlsrvPerfTest\SqlsrvUtil;
/** include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
* @Iterations(1000)
*/ class SqlsrvConnectionBench extends CRUDBaseBenchmark
class SqlsrvConnectionBench{ {
/* /*
* Opens a connection and closes it immediately * Opens a connection and closes it immediately
*/ */
public function benchConnectAndDisconnect(){ public function benchConnectAndDisconnect()
{
$conn = SqlsrvUtil::connect(); $conn = SqlsrvUtil::connect();
SqlsrvUtil::disconnect( $conn ); SqlsrvUtil::disconnect( $conn );
} }

View file

@ -1,15 +1,17 @@
<?php <?php
use SqlsrvPerfTest\SqlsrvUtil; use SqlsrvPerfTest\SqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect"}) * @BeforeMethods({"connect"})
* @AfterMethods({"disconnect"}) * @AfterMethods({"disconnect"})
*/ */
class SqlsrvCreateDbTableProcBench{ class SqlsrvCreateDbTableProcBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
@ -17,7 +19,8 @@ class SqlsrvCreateDbTableProcBench{
* Each iteration creates a database, a table and a stored procedure in that database and drops the database at the end. * Each iteration creates a database, a table and a stored procedure in that database and drops the database at the end.
* Note that, ODBC SQLExecDirect function are used to execute all the queries. * Note that, ODBC SQLExecDirect function are used to execute all the queries.
*/ */
public function benchCreateDbTableProc(){ public function benchCreateDbTableProc()
{
$randomNum = rand(); $randomNum = rand();
$databaseName = "test_db_$randomNum"; $databaseName = "test_db_$randomNum";
$tableName = "test_table_$randomNum"; $tableName = "test_table_$randomNum";
@ -26,7 +29,8 @@ class SqlsrvCreateDbTableProcBench{
SqlsrvUtil::dropDatabase( $this->conn, $databaseName ); SqlsrvUtil::dropDatabase( $this->conn, $databaseName );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -1,35 +1,42 @@
<?php <?php
use SqlsrvPerfTest\SqlsrvUtil; use SqlsrvPerfTest\SqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"})
* @AfterMethods({ "dropTable", "disconnect"}) * @AfterMethods({ "dropTable", "disconnect"})
*/ */
class SqlsrvDeleteBench{ class SqlsrvDeleteBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
private $insertValues; private $insertValues;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = SqlsrvUtil::generateInsertValues(); $this->insertValues = SqlsrvUtil::generateInsertValues();
} }
public function insertWithPrepare(){ public function insertWithPrepare()
for ( $i=0; $i<100; $i++ ){ {
for ( $i=0; $i<SqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
} }
@ -37,17 +44,21 @@ class SqlsrvDeleteBench{
* Each iteration inserts 1000 rows into the table, benchDelete deletes top row from the table 1000 times. * Each iteration inserts 1000 rows into the table, benchDelete deletes top row from the table 1000 times.
* Note that, every delete calls prepare and execute APIs. * Note that, every delete calls prepare and execute APIs.
*/ */
public function benchDelete(){ public function benchDelete()
for( $i=0; $i<100; $i++ ){ {
for( $i=0; $i<SqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
SqlsrvUtil::delete( $this->conn, $this->tableName ); SqlsrvUtil::delete( $this->conn, $this->tableName );
} }
} }
public function dropTable(){ public function dropTable()
{
SqlsrvUtil::dropTable( $this->conn, $this->tableName ); SqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }

View file

@ -1,36 +1,40 @@
<?php <?php
use SqlsrvPerfTest\SqlsrvUtil; use SqlsrvPerfTest\SqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare"})
* @AfterMethods({ "dropTable", "disconnect"}) * @AfterMethods({ "dropTable", "disconnect"})
*/ */
class SqlsrvFetchBench extends CRUDBaseBenchmark
{
class SqlsrvFetchBench{
private $conn; private $conn;
private $tableName; private $tableName;
private $insertValues; private $insertValues;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = SqlsrvUtil::generateInsertValues(); $this->insertValues = SqlsrvUtil::generateInsertValues();
} }
public function insertWithPrepare(){ public function insertWithPrepare()
{
SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
@ -38,17 +42,21 @@ class SqlsrvFetchBench{
* Each iteration inserts a row into the table, benchFetchWithPrepare() fetches that row 1000 times. * Each iteration inserts a row into the table, benchFetchWithPrepare() fetches that row 1000 times.
* Note that, every fetch calls prepare, execute and fetch APIs. * Note that, every fetch calls prepare, execute and fetch APIs.
*/ */
public function benchFetchWithPrepare(){ public function benchFetchWithPrepare()
for( $i=0; $i<100; $i++){ {
for( $i=0; $i<SqlsrvUtil::$loopsPerCRUDIter; $i++)
{
SqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName ); SqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName );
} }
} }
public function dropTable(){ public function dropTable()
{
SqlsrvUtil::dropTable( $this->conn, $this->tableName ); SqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -6,27 +6,32 @@ use SqlsrvPerfTest\SqlsrvUtil;
* @BeforeMethods({"connect", "setTableName" }) * @BeforeMethods({"connect", "setTableName" })
* @AfterMethods({ "disconnect"}) * @AfterMethods({ "disconnect"})
*/ */
class SqlsrvFetchLargeBench{ class SqlsrvFetchLargeBench
{
private $conn; private $conn;
private $tableName; private $tableName;
public function setTableName(){ public function setTableName()
{
//Assumes the table is already populated with data //Assumes the table is already populated with data
$this->tableName = "LargeDB.dbo.datatypes"; $this->tableName = "LargeDB.dbo.datatypes";
} }
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
/* /*
* Each iteration calls prepare, execute and fetch APIs to fetch the already populdated data * Each iteration calls prepare, execute and fetch APIs to fetch the already populdated data
*/ */
public function benchFetchWithPrepare(){ public function benchFetchWithPrepare()
{
SqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName ); SqlsrvUtil::fetchWithPrepare( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -1,47 +1,56 @@
<?php <?php
use SqlsrvPerfTest\SqlsrvUtil; use SqlsrvPerfTest\SqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues"})
* @AfterMethods({"dropTable","disconnect"}) * @AfterMethods({"dropTable","disconnect"})
*/ */
class SqlsrvInsertBench{ class SqlsrvInsertBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
private $insertValues; private $insertValues;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = SqlsrvUtil::generateInsertValues(); $this->insertValues = SqlsrvUtil::generateInsertValues();
} }
/** /**
* Each iteration inserts 1000 rows into the table. * Each iteration inserts 1000 rows into the table.
* Note that, every insertion calls prepare, bindParam and execute APIs. * Note that, every insertion calls prepare, bindParam and execute APIs.
*/ */
public function benchInsertWithPrepare(){ public function benchInsertWithPrepare()
for( $i=0; $i<100; $i++ ){ {
for( $i=0; $i<SqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
} }
public function dropTable(){ public function dropTable()
{
SqlsrvUtil::dropTable( $this->conn, $this->tableName ); SqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -6,21 +6,25 @@ use SqlsrvPerfTest\SqlsrvUtil;
* @BeforeMethods({"connect"}) * @BeforeMethods({"connect"})
* @AfterMethods({"disconnect"}) * @AfterMethods({"disconnect"})
*/ */
class SqlsrvSelectVersionBench{ class SqlsrvSelectVersionBench
{
private $conn; private $conn;
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
/* /*
* Each iteration calls execDirect API to fetch @@Version * Each iteration calls execDirect API to fetch @@Version
*/ */
public function benchSelectVersion(){ public function benchSelectVersion()
{
$version = SqlsrvUtil::selectVersion( $this->conn ); $version = SqlsrvUtil::selectVersion( $this->conn );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }
} }

View file

@ -1,12 +1,13 @@
<?php <?php
use SqlsrvPerfTest\SqlsrvUtil; use SqlsrvPerfTest\SqlsrvUtil;
include_once __DIR__ . "/../../lib/CRUDBaseBenchmark.php";
/** /**
* @Iterations(1000)
* @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare", "generateUpdateValues", "generateUpdateParams"}) * @BeforeMethods({"connect", "setTableName", "createTable", "generateInsertValues", "insertWithPrepare", "generateUpdateValues", "generateUpdateParams"})
* @AfterMethods({ "dropTable", "disconnect"}) * @AfterMethods({ "dropTable", "disconnect"})
*/ */
class SqlsrvUpdateBench{ class SqlsrvUpdateBench extends CRUDBaseBenchmark
{
private $conn; private $conn;
private $tableName; private $tableName;
@ -14,48 +15,59 @@ class SqlsrvUpdateBench{
private $updateValues; private $updateValues;
private $updateParams; private $updateParams;
public function setTableName(){ public function setTableName()
{
$this->tableName = "datatypes_".rand(); $this->tableName = "datatypes_".rand();
} }
public function connect(){ public function connect()
{
$this->conn = SqlsrvUtil::connect(); $this->conn = SqlsrvUtil::connect();
} }
public function createTable(){ public function createTable()
{
SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName ); SqlsrvUtil::createCRUDTable( $this->conn, $this->tableName );
} }
public function generateInsertValues(){ public function generateInsertValues()
{
$this->insertValues = SqlsrvUtil::generateInsertValues(); $this->insertValues = SqlsrvUtil::generateInsertValues();
} }
public function insertWithPrepare(){ public function insertWithPrepare()
{
SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues ); SqlsrvUtil::insertWithPrepare( $this->conn, $this->tableName, $this->insertValues );
} }
public function generateUpdateValues(){ public function generateUpdateValues()
{
$this->updateValues = SqlsrvUtil::generateUpdateValues(); $this->updateValues = SqlsrvUtil::generateUpdateValues();
} }
public function generateUpdateParams(){ public function generateUpdateParams()
{
$this->updateParams = SqlsrvUtil::generateUpdateParams(); $this->updateParams = SqlsrvUtil::generateUpdateParams();
} }
/** /**
* Each iteration inserts a row into the table, updateWithPrepare() updates that row 1000 times. * Each iteration inserts a row into the table, updateWithPrepare() updates that row 1000 times.
* Note that, every update calls prepare, bindParam and execute APIs. * Note that, every update calls prepare, bindParam and execute APIs.
*/ */
public function benchUpdateWithPrepare(){ public function benchUpdateWithPrepare()
for( $i=0; $i<100; $i++ ){ {
for( $i=0; $i<SqlsrvUtil::$loopsPerCRUDIter; $i++ )
{
$stmt = SqlsrvUtil::updateWithPrepare( $this->conn, $this->tableName, $this->updateValues, $this->updateParams ); $stmt = SqlsrvUtil::updateWithPrepare( $this->conn, $this->tableName, $this->updateValues, $this->updateParams );
} }
} }
public function dropTable(){ public function dropTable()
{
SqlsrvUtil::dropTable( $this->conn, $this->tableName ); SqlsrvUtil::dropTable( $this->conn, $this->tableName );
} }
public function disconnect(){ public function disconnect()
{
SqlsrvUtil::disconnect( $this->conn ); SqlsrvUtil::disconnect( $this->conn );
} }

View file

@ -0,0 +1,9 @@
<?php
/**
* @Iterations(1000)
*/
abstract class CRUDBaseBenchmark
{
}
?>

View file

@ -2,32 +2,41 @@
namespace PDOSqlsrvPerfTest; namespace PDOSqlsrvPerfTest;
use PDO; use PDO;
class PDOSqlsrvUtil{ class PDOSqlsrvUtil
{
public static function connect(){ public static $loopsPerCRUDIter = 100;
public static function connect()
{
require dirname(__FILE__).DIRECTORY_SEPARATOR.'connect.php'; require dirname(__FILE__).DIRECTORY_SEPARATOR.'connect.php';
try{ try
{
$conn = new PDO( "sqlsrv:Server=$server; Database=$database; ConnectionPooling=$pooling; MultipleActiveResultSets=$mars" , $uid, $pwd ); $conn = new PDO( "sqlsrv:Server=$server; Database=$database; ConnectionPooling=$pooling; MultipleActiveResultSets=$mars" , $uid, $pwd );
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn; return $conn;
} }
catch( PDOException $e ){ catch( PDOException $e )
{
var_dump( $e ); var_dump( $e );
exit; exit;
} }
} }
public static function disconnect( $conn ){ public static function disconnect( $conn )
{
$conn = null; $conn = null;
} }
public static function selectVersion( $conn ){ public static function selectVersion( $conn )
{
$sql = "SELECT @@Version"; $sql = "SELECT @@Version";
$stmt = self::query( $conn, $sql ); $stmt = self::query( $conn, $sql );
return self::fetch( $stmt ); return self::fetch( $stmt );
} }
public static function createDbTableProc( $conn, $databaseName, $tableName, $procName ){ public static function createDbTableProc( $conn, $databaseName, $tableName, $procName )
{
$tableParams = "id INTEGER, name VARCHAR(32), value INTEGER, start_date DATE, time_added TIMESTAMP, set_time TIME(7)"; $tableParams = "id INTEGER, name VARCHAR(32), value INTEGER, start_date DATE, time_added TIMESTAMP, set_time TIME(7)";
$procParams = "@id INTEGER, @name VARCHAR(32)"; $procParams = "@id INTEGER, @name VARCHAR(32)";
$procTextBase = "SET NOCOUNT ON; SELECT id, name, value FROM $databaseName.$tableName WHERE id = @id AND name = @name"; $procTextBase = "SET NOCOUNT ON; SELECT id, name, value FROM $databaseName.$tableName WHERE id = @id AND name = @name";
@ -37,7 +46,8 @@ class PDOSqlsrvUtil{
self::createStoredProc( $conn, $procName, $procParams, $procTextBase ); self::createStoredProc( $conn, $procName, $procParams, $procTextBase );
} }
public static function generateInsertValues(){ public static function generateInsertValues()
{
$vcharVal = "test string"; $vcharVal = "test string";
$nvcharVal = "wstring"; $nvcharVal = "wstring";
$intVal = 3; $intVal = 3;
@ -52,7 +62,8 @@ class PDOSqlsrvUtil{
return $values; return $values;
} }
public static function generateUpdateValues(){ public static function generateUpdateValues()
{
$vcharVal = "test string updated"; $vcharVal = "test string updated";
$nvcharVal = "wstring updated"; $nvcharVal = "wstring updated";
$intVal = 5; $intVal = 5;
@ -67,7 +78,8 @@ class PDOSqlsrvUtil{
return $updatedValues; return $updatedValues;
} }
public static function generateUpdateParams(){ public static function generateUpdateParams()
{
$fieldNames = array( $fieldNames = array(
"vstring", "vstring",
"nvstring", "nvstring",
@ -81,41 +93,47 @@ class PDOSqlsrvUtil{
"dtoffset"); "dtoffset");
$params = ""; $params = "";
foreach( $fieldNames as $fieldName ){ foreach( $fieldNames as $fieldName )
{
$params = $params.$fieldName."=?,"; $params = $params.$fieldName."=?,";
} }
$params = rtrim($params,", "); $params = rtrim($params,", ");
return $params; return $params;
} }
public static function insertWithPrepare( $conn, $tableName, $values ){ public static function insertWithPrepare( $conn, $tableName, $values )
{
$sql = "INSERT INTO $tableName VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; $sql = "INSERT INTO $tableName VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = self::prepare( $conn, $sql ); $stmt = self::prepare( $conn, $sql );
self::bindParams( $stmt, $values ); self::bindParams( $stmt, $values );
self::execute( $stmt ); self::execute( $stmt );
} }
public static function fetchWithPrepare( $conn, $tableName ){ public static function fetchWithPrepare( $conn, $tableName )
{
$sql = "SELECT * FROM $tableName"; $sql = "SELECT * FROM $tableName";
$stmt = self::prepare( $conn, $sql ); $stmt = self::prepare( $conn, $sql );
self::execute( $stmt ); self::execute( $stmt );
while ( $row = self::fetch( $stmt )){} while ( $row = self::fetch( $stmt )){}
} }
public static function deleteWithPrepare( $conn, $tableName ){ public static function deleteWithPrepare( $conn, $tableName )
{
$sql = "DELETE TOP (1) FROM $tableName"; $sql = "DELETE TOP (1) FROM $tableName";
$stmt = self::prepare( $conn, $sql ); $stmt = self::prepare( $conn, $sql );
self::execute( $stmt ); self::execute( $stmt );
} }
public static function updateWithPrepare( $conn, $tableName, $updateValues, $params ){ public static function updateWithPrepare( $conn, $tableName, $updateValues, $params )
{
$sql = "UPDATE $tableName SET ".$params; $sql = "UPDATE $tableName SET ".$params;
$stmt = self::prepare( $conn, $sql ); $stmt = self::prepare( $conn, $sql );
self::bindParams( $stmt, $updateValues ); self::bindParams( $stmt, $updateValues );
self::execute( $stmt ); self::execute( $stmt );
} }
private function bindParams( $stmt, $values ){ private function bindParams( $stmt, $values )
{
//This functionn assumes the fields are from createCRUDTable() //This functionn assumes the fields are from createCRUDTable()
self::bindParam( $stmt, 1, $values[0], PDO::PARAM_STR); self::bindParam( $stmt, 1, $values[0], PDO::PARAM_STR);
self::bindParam( $stmt, 2, $values[1], PDO::PARAM_STR); self::bindParam( $stmt, 2, $values[1], PDO::PARAM_STR);
@ -129,7 +147,8 @@ class PDOSqlsrvUtil{
self::bindParam( $stmt, 10, $values[9], PDO::PARAM_STR); self::bindParam( $stmt, 10, $values[9], PDO::PARAM_STR);
} }
public static function createCRUDTable( $conn, $tableName ){ public static function createCRUDTable( $conn, $tableName )
{
$fields = array( $fields = array(
"vstring" => "VARCHAR(64)", "vstring" => "VARCHAR(64)",
"nvstring" => "NVARCHAR(64)", "nvstring" => "NVARCHAR(64)",
@ -142,86 +161,106 @@ class PDOSqlsrvUtil{
"vbin" => "VARBINARY", "vbin" => "VARBINARY",
"dtoffset" => "DATETIMEOFFSET"); "dtoffset" => "DATETIMEOFFSET");
$params = ""; $params = "";
foreach( $fields as $fieldName => $type ){ foreach( $fields as $fieldName => $type )
{
$params .= $fieldName." ".$type.","; $params .= $fieldName." ".$type.",";
} }
$params = rtrim($params,", "); $params = rtrim($params,", ");
self::createTable( $conn, $tableName, $params ); self::createTable( $conn, $tableName, $params );
} }
private function createDatabase( $conn, $dbName ){ private function createDatabase( $conn, $dbName )
{
$sql = "CREATE DATABASE $dbName"; $sql = "CREATE DATABASE $dbName";
$conn->exec( $sql ); $conn->exec( $sql );
} }
public static function dropDatabase( $conn, $dbName ){ public static function dropDatabase( $conn, $dbName )
{
$sql = "USE MASTER;DROP DATABASE $dbName"; $sql = "USE MASTER;DROP DATABASE $dbName";
$conn->exec( $sql ); $conn->exec( $sql );
} }
public static function createTable( $conn, $tableName, $params ){ public static function createTable( $conn, $tableName, $params )
{
$sql = "CREATE TABLE $tableName ($params)"; $sql = "CREATE TABLE $tableName ($params)";
$conn->exec( $sql ); $conn->exec( $sql );
} }
public static function dropTable( $conn, $tableName ){ public static function dropTable( $conn, $tableName )
{
$sql = "DROP TABLE $tableName"; $sql = "DROP TABLE $tableName";
$conn->exec( $sql ); $conn->exec( $sql );
} }
private function useDatabase( $conn, $dbName ){ private function useDatabase( $conn, $dbName )
{
$sql = "USE $dbName"; $sql = "USE $dbName";
$conn->exec( $sql ); $conn->exec( $sql );
} }
private function createStoredProc( $conn, $procName, $params, $text ){ private function createStoredProc( $conn, $procName, $params, $text )
{
$sql = "CREATE PROCEDURE $procName $params AS $text"; $sql = "CREATE PROCEDURE $procName $params AS $text";
$conn->exec( $sql ); $conn->exec( $sql );
} }
private function dropStoredProc( $conn, $procName ){ private function dropStoredProc( $conn, $procName )
{
$sql = "DROP PROCEDURE $procName"; $sql = "DROP PROCEDURE $procName";
$conn->exec( $sql ); $conn->exec( $sql );
} }
private function query( $conn, $sql ){ private function query( $conn, $sql )
try{ {
try
{
return $conn->query( $sql ); return $conn->query( $sql );
} }
catch( PDOException $e ){ catch( PDOException $e )
{
var_dump( $e ); var_dump( $e );
exit; exit;
} }
} }
private function fetch( $stmt ){ private function fetch( $stmt )
{
return $stmt->fetch(); return $stmt->fetch();
} }
private function prepare( $conn, $sql ){ private function prepare( $conn, $sql )
try{ {
try
{
$stmt = $conn->prepare( $sql ); $stmt = $conn->prepare( $sql );
if( $stmt === false ){ if( $stmt === false )
{
die( "Failed to prepare\n"); die( "Failed to prepare\n");
} }
return $stmt; return $stmt;
} }
catch( PDOException $e ){ catch( PDOException $e )
{
var_dump( $e ); var_dump( $e );
exit; exit;
} }
} }
private function execute( $stmt ){ private function execute( $stmt )
{
$ret = $stmt->execute(); $ret = $stmt->execute();
if( $ret === false ){ if( $ret === false )
{
die( "Failed to execute\n" ); die( "Failed to execute\n" );
} }
} }
private function bindParam( $stmt, $index, $value, $type ){ private function bindParam( $stmt, $index, $value, $type )
{
$ret = $stmt->bindParam( $index, $value, $type ); $ret = $stmt->bindParam( $index, $value, $type );
if ( $ret === false){ if ( $ret === false)
{
die( "Faild to bind\n"); die( "Faild to bind\n");
} }
} }

View file

@ -2,35 +2,45 @@
namespace SqlsrvPerfTest; namespace SqlsrvPerfTest;
class SqlsrvUtil{ class SqlsrvUtil
{
public static $loopsPerCRUDIter = 100;
public static function connect(){ public static function connect()
{
require dirname(__FILE__).DIRECTORY_SEPARATOR.'connect.php'; require dirname(__FILE__).DIRECTORY_SEPARATOR.'connect.php';
$options = array( "Database"=>$database, "UID"=>$uid, "PWD"=>$pwd, "ConnectionPooling"=>$pooling, "MultipleActiveResultSets"=>$mars ); $options = array( "Database"=>$database, "UID"=>$uid, "PWD"=>$pwd, "ConnectionPooling"=>$pooling, "MultipleActiveResultSets"=>$mars );
$conn = sqlsrv_connect( $server, $options ); $conn = sqlsrv_connect( $server, $options );
if ( $conn === false ){ if ( $conn === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
return $conn; return $conn;
} }
public static function disconnect( $conn ){ public static function disconnect( $conn )
if ( $conn === false || $conn === null ){ {
if ( $conn === false || $conn === null )
{
die( print_r( "Invalid connection resource\n")); die( print_r( "Invalid connection resource\n"));
} }
$ret = sqlsrv_close( $conn ); $ret = sqlsrv_close( $conn );
if ( $ret === false ){ if ( $ret === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
} }
public static function selectVersion( $conn ){ public static function selectVersion( $conn )
{
$sql = "SELECT @@Version"; $sql = "SELECT @@Version";
$stmt = self::query( $conn, $sql ); $stmt = self::query( $conn, $sql );
return self::fetchArray( $stmt ); return self::fetchArray( $stmt );
} }
public static function createDbTableProc( $conn, $databaseName, $tableName, $procName ){ public static function createDbTableProc( $conn, $databaseName, $tableName, $procName )
{
$tableParams = "id INTEGER, name VARCHAR(32), value INTEGER, start_date DATE, time_added TIMESTAMP, set_time TIME(7)"; $tableParams = "id INTEGER, name VARCHAR(32), value INTEGER, start_date DATE, time_added TIMESTAMP, set_time TIME(7)";
$procParams = "@id INTEGER, @name VARCHAR(32)"; $procParams = "@id INTEGER, @name VARCHAR(32)";
$procTextBase = "SET NOCOUNT ON; SELECT id, name, value FROM $databaseName.$tableName WHERE id = @id AND name = @name"; $procTextBase = "SET NOCOUNT ON; SELECT id, name, value FROM $databaseName.$tableName WHERE id = @id AND name = @name";
@ -40,7 +50,8 @@ class SqlsrvUtil{
self::createStoredProc( $conn, $procName, $procParams, $procTextBase ); self::createStoredProc( $conn, $procName, $procParams, $procTextBase );
} }
public static function generateInsertValues(){ public static function generateInsertValues()
{
$vcharVal = "test string"; $vcharVal = "test string";
$nvcharVal = "wstring"; $nvcharVal = "wstring";
$intVal = 3; $intVal = 3;
@ -55,7 +66,8 @@ class SqlsrvUtil{
return $values; return $values;
} }
public static function generateUpdateValues(){ public static function generateUpdateValues()
{
$vcharVal = "test string updated"; $vcharVal = "test string updated";
$nvcharVal = "wstring updated"; $nvcharVal = "wstring updated";
$intVal = 5; $intVal = 5;
@ -70,7 +82,8 @@ class SqlsrvUtil{
return $updatedValues; return $updatedValues;
} }
public static function generateUpdateParams(){ public static function generateUpdateParams()
{
$fieldNames = array( $fieldNames = array(
"vstring", "vstring",
"nvstring", "nvstring",
@ -84,33 +97,38 @@ class SqlsrvUtil{
"dtoffset"); "dtoffset");
$params = ""; $params = "";
foreach( $fieldNames as $fieldName ){ foreach( $fieldNames as $fieldName )
{
$params = $params.$fieldName."=?,"; $params = $params.$fieldName."=?,";
} }
$params = rtrim($params,", "); $params = rtrim($params,", ");
return $params; return $params;
} }
public static function insertWithPrepare( $conn, $tableName, $values ){ public static function insertWithPrepare( $conn, $tableName, $values )
{
$sql = "INSERT INTO $tableName VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; $sql = "INSERT INTO $tableName VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = self::prepare( $conn, $sql, $values ); $stmt = self::prepare( $conn, $sql, $values );
self::execute( $stmt ); self::execute( $stmt );
} }
public static function updateWithPrepare( $conn, $tableName, $updateValues, $params ){ public static function updateWithPrepare( $conn, $tableName, $updateValues, $params )
{
$sql = "UPDATE $tableName SET ".$params; $sql = "UPDATE $tableName SET ".$params;
$stmt = self::prepare( $conn, $sql, $updateValues ); $stmt = self::prepare( $conn, $sql, $updateValues );
self::execute( $stmt ); self::execute( $stmt );
} }
public static function fetchWithPrepare( $conn, $tableName ){ public static function fetchWithPrepare( $conn, $tableName )
{
$sql = "SELECT * FROM $tableName"; $sql = "SELECT * FROM $tableName";
$stmt = self::prepare( $conn, $sql, array()); $stmt = self::prepare( $conn, $sql, array());
self::execute( $stmt ); self::execute( $stmt );
while( $row = self::fetchArray( $stmt ) ) {} while( $row = self::fetchArray( $stmt ) ) {}
} }
public static function createCRUDTable( $conn, $tableName ){ public static function createCRUDTable( $conn, $tableName )
{
$fields = array( $fields = array(
"vstring" => "VARCHAR(64)", "vstring" => "VARCHAR(64)",
"nvstring" => "NVARCHAR(64)", "nvstring" => "NVARCHAR(64)",
@ -123,108 +141,131 @@ class SqlsrvUtil{
"vbin" => "VARBINARY", "vbin" => "VARBINARY",
"dtoffset" => "DATETIMEOFFSET"); "dtoffset" => "DATETIMEOFFSET");
$params = ""; $params = "";
foreach( $fields as $fieldName => $type ){ foreach( $fields as $fieldName => $type )
{
$params .= $fieldName." ".$type.","; $params .= $fieldName." ".$type.",";
} }
$params = rtrim($params,", "); $params = rtrim($params,", ");
self::createTable( $conn, $tableName, $params ); self::createTable( $conn, $tableName, $params );
} }
public static function query( $conn, $sql ){ public static function query( $conn, $sql )
{
$stmt = sqlsrv_query( $conn, $sql ); $stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false ){ if( $stmt === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
return $stmt; return $stmt;
} }
public static function fetch( $stmt ){ public static function fetch( $stmt )
{
$ret = sqlsrv_fetch( $stmt ); $ret = sqlsrv_fetch( $stmt );
if( $ret === false ){ if( $ret === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
return $ret; return $ret;
} }
public static function fetchArray( $stmt ){ public static function fetchArray( $stmt )
{
$row = sqlsrv_fetch_array( $stmt ); $row = sqlsrv_fetch_array( $stmt );
if ( $row === false ){ if ( $row === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
return $row; return $row;
} }
public static function getField( $stmt, $index ){ public static function getField( $stmt, $index )
{
return sqlsrv_get_field( $stmt, $index ); return sqlsrv_get_field( $stmt, $index );
} }
private function createDatabase( $conn, $dbName ){ private function createDatabase( $conn, $dbName )
{
$sql = "CREATE DATABASE $dbName"; $sql = "CREATE DATABASE $dbName";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
public static function dropDatabase( $conn, $dbName ){ public static function dropDatabase( $conn, $dbName )
{
$sql = "USE MASTER;DROP DATABASE $dbName"; $sql = "USE MASTER;DROP DATABASE $dbName";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
public static function createTable( $conn, $tableName, $params ){ public static function createTable( $conn, $tableName, $params )
{
$sql = "CREATE TABLE $tableName ($params)"; $sql = "CREATE TABLE $tableName ($params)";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
public static function dropTable( $conn, $tableName ){ public static function dropTable( $conn, $tableName )
{
$sql = "DROP TABLE $tableName"; $sql = "DROP TABLE $tableName";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
private function useDatabase( $conn, $dbName ){ private function useDatabase( $conn, $dbName )
{
$sql = "USE $dbName"; $sql = "USE $dbName";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
private function createStoredProc( $conn, $procName, $params, $text ){ private function createStoredProc( $conn, $procName, $params, $text )
{
$sql = "CREATE PROCEDURE $procName $params AS $text"; $sql = "CREATE PROCEDURE $procName $params AS $text";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
private function dropStoredProc( $conn, $procName ){ private function dropStoredProc( $conn, $procName )
{
$sql = "DROP PROCEDURE $procName"; $sql = "DROP PROCEDURE $procName";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
private function insert( $conn, $tableName, $values ){ private function insert( $conn, $tableName, $values )
{
$sql = "INSERT INTO $tableName values ($values)"; $sql = "INSERT INTO $tableName values ($values)";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
private function update( $conn, $tableName, $params, $condition ){ private function update( $conn, $tableName, $params, $condition )
{
$sql = "UPDATE $tableName SET $params WHERE $condition"; $sql = "UPDATE $tableName SET $params WHERE $condition";
self::query( $sql ); self::query( $sql );
} }
public function delete( $conn, $tableName){ public function delete( $conn, $tableName)
{
$sql = "DELETE TOP (1) FROM $tableName"; $sql = "DELETE TOP (1) FROM $tableName";
self::query( $conn, $sql ); self::query( $conn, $sql );
} }
public function deleteWithPrepare( $conn, $tableName ){ public function deleteWithPrepare( $conn, $tableName )
{
$sql = "DELETE TOP (1) FROM $tableName"; $sql = "DELETE TOP (1) FROM $tableName";
$stmt = self::prepare( $conn, $sql, array() ); $stmt = self::prepare( $conn, $sql, array() );
self::execute( $stmt ); self::execute( $stmt );
} }
private function prepare( $conn, $sql, $params ){ private function prepare( $conn, $sql, $params )
{
$stmt = sqlsrv_prepare( $conn, $sql, $params ); $stmt = sqlsrv_prepare( $conn, $sql, $params );
if( $stmt === false ){ if( $stmt === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
return $stmt; return $stmt;
} }
public function execute( $stmt ){ public function execute( $stmt )
{
$ret = sqlsrv_execute( $stmt ); $ret = sqlsrv_execute( $stmt );
if ( $ret === false ){ if ( $ret === false )
{
die( print_r( sqlsrv_errors(), true)); die( print_r( sqlsrv_errors(), true));
} }
} }

View file

@ -1,8 +1,9 @@
--The script can be run to read the results. You can filter out the results ran on a certain date by changing the date at the end. --The script can be run to read the results. You can filter out the results ran on a certain date by changing the date at the end.
DECLARE @convByteToMegabyte int = 1048576
select t1.ResultId, Test, Client, Server, Driver, Duration, Memory, Success, Team, StartTime from select t1.ResultId, Test, Client, Server, Driver, Duration, Memory, Success, Team, StartTime from
( (
select pr.ResultId, pr.Success, pt.TestName as Test, cl.HostName as Client, srv.HostName as Server, select pr.ResultId, pr.Success, pt.TestName as Test, cl.HostName as Client, srv.HostName as Server,
tm.TeamName as Team, st.value as Driver, bi.value as Duration, CAST(bi2.value AS decimal(10,2))/1048576 as Memory, dt.value as StartTime from tm.TeamName as Team, st.value as Driver, bi.value as Duration, CAST(bi2.value AS decimal(10,2))/@convByteToMegabyte as Memory, dt.value as StartTime from
KeyValueTableBigInt bi, KeyValueTableBigInt bi,
KeyValueTableBigInt bi2, KeyValueTableBigInt bi2,
KeyValueTableString st, KeyValueTableString st,
@ -20,5 +21,4 @@ and cl.ClientId = pr.ClientId
and pt.TestId = pr.TestId and pt.TestId = pr.TestId
and tm.TeamId = pr.TeamId and tm.TeamId = pr.TeamId
and srv.ServerId = pr.ServerId and srv.ServerId = pr.ServerId
) t1 where StartTime like '%2017-06-23%' ) t1 where StartTime like '%2017-06-23%'

View file

@ -755,7 +755,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( '-platform', '--PLATFORM', required=True, help='The name of the platform the tests run on' ) parser.add_argument( '-platform', '--PLATFORM', required=True, help='The name of the platform the tests run on' )
parser.add_argument( '-php-driver', '--PHP_DRIVER', default='both', help='Name of the PHP driver: sqlsrv, pdo_sqlsrv or both') parser.add_argument( '-php-driver', '--PHP_DRIVER', default='both', help='Name of the PHP driver: sqlsrv, pdo_sqlsrv or both')
parser.add_argument( '-test-only', '--TEST_ONLY', default='all', help='File name for only one test or all' ) parser.add_argument( '-testname', '--TESTNAME', default='all', help='File name for only one test or all' )
args = parser.parse_args() args = parser.parse_args()
# Start time is recorded only in the beginning of this script execution. So it is not benchmark specific. # Start time is recorded only in the beginning of this script execution. So it is not benchmark specific.
@ -769,7 +769,7 @@ if __name__ == '__main__':
print("Running the tests with default settings...") print("Running the tests with default settings...")
run_tests( args.PHP_DRIVER, args.TEST_ONLY ) run_tests( args.PHP_DRIVER, args.TESTNAME )
parse_and_store_results_all( test_db, result_db, args.PLATFORM, start_time, 0, 0 ) parse_and_store_results_all( test_db, result_db, args.PLATFORM, start_time, 0, 0 )
""" """
The following lines are commented out, because it already takes a long time to run the tests with the default settings. The following lines are commented out, because it already takes a long time to run the tests with the default settings.
@ -777,14 +777,14 @@ if __name__ == '__main__':
print("Running the tests with MARS ON...") print("Running the tests with MARS ON...")
enable_mars() enable_mars()
run_tests( args.PHP_DRIVER, args.TEST_ONLY ) run_tests( args.PHP_DRIVER, args.TESTNAME )
parse_and_store_results_all( test_db, result_db, args.PLATFORM, start_time, 1, 0 ) parse_and_store_results_all( test_db, result_db, args.PLATFORM, start_time, 1, 0 )
disable_mars() disable_mars()
print("Running the tests with Pooling ON...") print("Running the tests with Pooling ON...")
enable_pooling() enable_pooling()
run_tests( args.PHP_DRIVER, args.TEST_ONLY ) run_tests( args.PHP_DRIVER, args.TESTNAME )
parse_and_store_results_all( test_db, result_db, args.PLATFORM, start_time, 0, 1 ) parse_and_store_results_all( test_db, result_db, args.PLATFORM, start_time, 0, 1 )
disable_pooling() disable_pooling()
""" """