Skip to content

Commit 10ee1d3

Browse files
staabmclxmstaab
andauthored
Query Plan Analysis: Reduce default numberOfRowsNotRequiringIndex to 0 (#388)
* Reduce DEFAULT_SMALL_TABLE_THRESHOLD to 0 * fix * cs * Update RuntimeConfiguration.php * record Co-authored-by: Markus Staab <[email protected]>
1 parent cde6423 commit 10ee1d3

File tree

10 files changed

+679
-126
lines changed

10 files changed

+679
-126
lines changed

.phpstan-dba-mysqli.cache

Lines changed: 481 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/query-plan-analysis.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The analyzer is reporting problems related to queries not using index, full-tabl
77

88
## Signature
99

10-
`analyzeQueryPlans($numberOfAllowedUnindexedReads = true, $numberOfRowsNotRequiringIndex = QueryPlanAnalyzerMysql::DEFAULT_SMALL_TABLE_THRESHOLD)`
10+
`analyzeQueryPlans($numberOfAllowedUnindexedReads = true, $numberOfRowsNotRequiringIndex = QueryPlanAnalyzer::TABLES_WITHOUT_DATA)`
1111

1212
## Examples
1313

@@ -26,20 +26,26 @@ $config = new RuntimeConfiguration();
2626
$config->analyzeQueryPlans(100000);
2727
```
2828

29-
To disable the effiency analysis but just check for queries not using indices at all, pass `0`.
29+
To disable the effiency analysis but just check for queries not using indices at all, pass `0`:
3030

3131
```php
3232
$config = new RuntimeConfiguration();
3333
$config->analyzeQueryPlans(0);
3434
```
3535

36-
When running in environments in which only the database schema, but no data is available pass `$numberOfRowsNotRequiringIndex=0`.
36+
When running in environments in which only the database schema, but no data is available pass `$numberOfRowsNotRequiringIndex=0`:
3737

3838
```php
3939
$config = new RuntimeConfiguration();
40-
$config->analyzeQueryPlans(true, 0);
40+
$config->analyzeQueryPlans(true, QueryPlanAnalyzer::TABLES_WITHOUT_DATA);
4141
```
4242

43+
In case you are running a real database with production quality data, you should ignore tables with only few rows, to reduce false positives:
44+
45+
```php
46+
$config = new RuntimeConfiguration();
47+
$config->analyzeQueryPlans(true, QueryPlanAnalyzer::DEFAULT_SMALL_TABLE_THRESHOLD);
48+
```
4349

4450
**Note:** For a meaningful performance analysis it is vital to utilize a database, which containts data and schema as similar as possible to the production database.
4551

src/Analyzer/QueryPlanAnalyzer.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace staabm\PHPStanDba\Analyzer;
6+
7+
final class QueryPlanAnalyzer
8+
{
9+
/**
10+
* number of unindexed reads allowed before a query is considered inefficient.
11+
*/
12+
public const DEFAULT_UNINDEXED_READS_THRESHOLD = 100000;
13+
/**
14+
* allows analyzing queries even on empty database schemas.
15+
*/
16+
public const TABLES_WITHOUT_DATA = 0;
17+
/**
18+
* max number of rows in a table, for which we don't report errors, because using a index/table-scan wouldn't improve performance.
19+
* requires production quality data in the database at analysis time.
20+
*/
21+
public const DEFAULT_SMALL_TABLE_THRESHOLD = 5000;
22+
}

src/Analyzer/QueryPlanAnalyzerMysql.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
final class QueryPlanAnalyzerMysql
1313
{
1414
/**
15-
* number of unindexed reads allowed before a query is considered inefficient.
15+
* @deprecated use QueryPlanAnalyzer::DEFAULT_UNINDEXED_READS_THRESHOLD instead
1616
*/
17-
public const DEFAULT_UNINDEXED_READS_THRESHOLD = 100000;
17+
public const DEFAULT_UNINDEXED_READS_THRESHOLD = QueryPlanAnalyzer::DEFAULT_UNINDEXED_READS_THRESHOLD;
1818
/**
19-
* max number of rows in a table, for which we don't report errors, because using a index/table-scan wouldn't improve performance.
19+
* @deprecated use QueryPlanAnalyzer::TABLES_WITHOUT_DATA instead
2020
*/
21-
public const DEFAULT_SMALL_TABLE_THRESHOLD = 1000;
21+
public const TABLES_WITHOUT_DATA = QueryPlanAnalyzer::TABLES_WITHOUT_DATA;
22+
/**
23+
* @deprecated use QueryPlanAnalyzer::DEFAULT_SMALL_TABLE_THRESHOLD instead
24+
*/
25+
public const DEFAULT_SMALL_TABLE_THRESHOLD = QueryPlanAnalyzer::DEFAULT_SMALL_TABLE_THRESHOLD;
2226

2327
/**
2428
* @var PDO|mysqli

src/QueryReflection/RuntimeConfiguration.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace staabm\PHPStanDba\QueryReflection;
66

77
use PHPStan\Php\PhpVersion;
8-
use staabm\PHPStanDba\Analyzer\QueryPlanAnalyzerMysql;
8+
use staabm\PHPStanDba\Analyzer\QueryPlanAnalyzer;
99

1010
final class RuntimeConfiguration
1111
{
@@ -109,14 +109,15 @@ public function stringifyTypes(bool $stringify): self
109109
*
110110
* Requires a active database connection.
111111
*
112-
* @param bool|0|positive-int $numberOfAllowedUnindexedReads `true` to enable analysis with QueryPlanAnalyzerMysql::DEFAULT_UNINDEXED_READS_THRESHOLD. `false` to disable analysis.
112+
* @param bool|0|positive-int $numberOfAllowedUnindexedReads `true` to enable analysis with QueryPlanAnalyzer::DEFAULT_UNINDEXED_READS_THRESHOLD. `false` to disable analysis.
113113
* Otherwise the number of reads a query is allowed to execute, before it is considered inefficient.
114114
* `0` disables the efficiency checks but still scans for queries not using an index.
115-
* @param 0|positive-int $numberOfRowsNotRequiringIndex number of reads a query is allowed to execute, without requiring a index
115+
* @param 0|positive-int $numberOfRowsNotRequiringIndex number of reads a query is allowed to execute, without requiring a index.
116+
* for sane defaults see QueryPlanAnalyzer::TABLES_WITHOUT_DATA and QueryPlanAnalyzer::DEFAULT_SMALL_TABLE_THRESHOLD
116117
*
117118
* @return $this
118119
*/
119-
public function analyzeQueryPlans($numberOfAllowedUnindexedReads = true, $numberOfRowsNotRequiringIndex = QueryPlanAnalyzerMysql::DEFAULT_SMALL_TABLE_THRESHOLD): self
120+
public function analyzeQueryPlans($numberOfAllowedUnindexedReads = true, $numberOfRowsNotRequiringIndex = QueryPlanAnalyzer::TABLES_WITHOUT_DATA): self
120121
{
121122
$this->numberOfAllowedUnindexedReads = $numberOfAllowedUnindexedReads;
122123
$this->numberOfRowsNotRequiringIndex = $numberOfRowsNotRequiringIndex;

tests/default/config/.phpstan-dba-mysqli.cache

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/default/config/.phpstan-dba-pdo-mysql.cache

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/default/config/.phpunit-phpstan-dba-mysqli.cache

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/rules/config/.phpstan-dba-pdo-mysql.cache

Lines changed: 153 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)