Provare a scrivere qualcosa per convertire automaticamente da un risultato DB arbitrario (ad esempio, non sempre tutto dalla tabella x), a un risultato tipizzato PHP appropriato.Ottieni tipi di colonna tramite PDO (getColumnMeta è/lento /)
ho esteso la classe PDOStatement,
class Statement extends PDOStatement {
protected $pdo;
protected $transformer;
protected function __construct(PDO $pdo) {
$this->pdo = $pdo;
$this->transformer = $pdo->getTransformer();
}
public function fetchAll() {
$results = parent::fetchAll(PDO::FETCH_ASSOC);
if ($this->getTransformer()) $results = $this->completeResults($results);
return $results;
}
private function completeResults(array $results = []) {
if ($results == null || count($results) == 0) return null;
if ($results[0] == false || !is_array($results[0])) return null;
$index = 0;
$typeMap = [];
foreach ($results[0] as $column => $result) {
$meta = $this->getColumnMeta($index); // this is very painful
$typeMap[$column] = $meta['native_type'];
$index++;
}
$transformer = $this->getTransformer();
foreach ($results as $index => &$result) {
array_walk($result, function(&$value, $key) use ($typeMap, $transformer) {
$type = $typeMap[$key];
$value = $transformer->transformToPhpValue($value, $type);
});
}
return $results;
}
}
In precedenza, prima che io ero a conoscenza della DOP astrazione, stavo usando (nel mio caso specifico) il pg di serie _... metodi(). Usando pg_field_type($resource, $column);
, ho potuto recuperare il tipo di colonna, ed era relativamente veloce.
Ora, utilizzando il nuovo metodo (per me) PDO. Se io commento la parte del mio codice dove faccio la trasformazione, e corro 7 query consecutive:
time to complete: 9.5367431640625E-7 seconds
time to complete: 1.1920928955078E-6 seconds
time to complete: 9.5367431640625E-7 seconds
time to complete: 0 seconds
time to complete: 9.5367431640625E-7 seconds
time to complete: 0 seconds
time to complete: 0 seconds
con esso abilitati:
time to complete: 0.5777850151062 seconds
time to complete: 0.49124097824097 seconds
time to complete: 0.28375911712646 seconds
time to complete: 0.5946729183197 seconds
time to complete: 0.42177200317383 seconds
time to complete: 5.0067901611328E-6 seconds
time to complete: 0.42121982574463 seconds
Ecco// folle.
posso dire che è andare a prendere le informazioni di colonna ad uno ad uno per uno, cercando in miei log Postgres:
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=1114
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=1114
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=25
... like 30 more of these ...
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=25
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=23
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=23
LOG: statement: SELECT TYPNAME FROM PG_TYPE WHERE OID=23
Le query variano in complessità da
SELECT
p.modified_at, ... ~ 30 fields ..., r.level AS id_level
FROM table_p AS p
LEFT JOIN table_a AS a ON (p.owner = a.id)
LEFT JOIN table_a0 AS a0 ON (p.reporter = a0.id)
LEFT JOIN table_r AS r ON (p.id = r.id)
WHERE (p.id = 1)
a poco SELECT * FROM table_a AS a;
Quindi, suppongo che la domanda sia: c'è un modo migliore per farlo? C'è un modo per farlo senza influire sulla velocità del mio codice? 7 query sono sulla fascia bassa di query consecutive eseguite per richiesta, quindi è qualcosa che vorrei affrontare.
Credo che per ora, faresti meglio a farlo usando php perché è ancora sperimentale. Sarà l'anno luce più veloce. – cpugourou
Se si prevede di utilizzare solo Postgresql per il proprio progetto, si consiglia vivamente di utilizzare la libreria pgsql nativa al posto di PDO. La PDO è più lenta ed espone meno funzioni. Una risposta per il tuo tipo di problema potrebbe essere http://stackoverflow.com/questions/31643297/pg-query-result-contains-strings-instead-of-integer-numeric/31740990#31740990 – greg
@greg yeah questo è quello che stavo usando prima. Sfortunatamente voleva dire scrivere molte delle funzionalità con cui PDO viene fornito con ... –