質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

解決済

PHPでデータベースからデータを取得する際、とても時間がかかってしまうのを改善したい

bws
bws

総合スコア98

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

3回答

0評価

0クリップ

253閲覧

投稿2019/08/15 08:36

編集2019/08/16 00:47

やりたいこと

下記テーブルから商品の
sum(sales_products.quantity)(注文数合計)
categories.taxonomy_id(カテゴリー分類ID)
sales.office_id AS office_id(販売事業所ID)

categories.taxonomy_id(カテゴリー分類)
sales.office_id AS office_id(販売事業所ID)
でグループ化して取得したい。

困っていること

salesテーブル => orderテーブル, event_salesテーブル, event_orderテーブル
sales_productsテーブル => order_productsテーブルevent_sales_productsテーブル, event_order_productsテーブル

といったように似たテーブルが他に3種類あり、
下記コードのように合計で3回データベースから取得するのでかなりの時間がかかってしまいます。

少しでもパフォーマンスをよくしたいのですが、どのようにしたらよいでしょうか?
アドバイスお願いします。

テーブル

sales(注文)テーブル (5万くらい)
|id|shop_id|office_id|date|
|:--|:--:|--:|
|1|1|1|0000-00-00|
|2|1|2|0000-00-00|
|3|1|2|0000-00-00|

sql

// CREATE CREATE TABLE `sales` ( `id` int(11) NOT NULL AUTO_INCREMENT, `shop_id` int(11) NOT NULL, `office_id` int(11) NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=53158 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

sales_products(注文商品)テーブル(300万くらい)
|id|sales_id|product_id|quantity|
|:--|:--:|--:|
|1|1|1|5|
|2|1|3|7|
|3|1|2|7|

sql

// CREATE CREATE TABLE `sales_products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `sales_id` int(11) NOT NULL, `product_id` int(11) NOT NULL, `quantity` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2504749 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

products(商品)テーブル(3万くらい)

idcategory_idname
11商品1
1商品2
1商品3

sql

// CREATE CREATE TABLE `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `category_id` int(11) NOT NULL, `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=28449 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; // INSERT $sql = "INSERT INTO products (category_id, name) VALUES (:category_id, :name)";

categories(商品カテゴリー)テーブル(200くらい)

idtaxonomy_idname
11カテゴリー1
21カテゴリー2
31カテゴリー3

sql

// CREATE文 CREATE TABLE `categories` ( `id` int(11) NOT NULL AUTO_INCREMENT, `taxonomy_id` int(11) NOT NULL, `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=174 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

コード

php

$sql = "SELECT sum(sales_products.quantity) AS sum_quantity, categories.taxonomy_id AS taxonomy, sales.office_id AS office_id FROM sales, sales_products, products, categories WHERE sales.id = sales_product.sales_id AND sales_products.product_id = products.id AND product.category_id = categories.id AND (sales.date BETWEEN :from AND :to) GROUP BY categories.taxonomy_id, sales.office_id"; $stmt = $this->dbh->prepare($sql); $data = array( ':from' => $from, ':to' => $to ); $stmt->execute($data); $rec = $stmt->fetchAll(PDO::FETCH_ASSOC);

php

// 他テーブルも以下のように取得 $sql = "SELECT sum(order_products.quantity) AS sum_quantity, categories.taxonomy_id AS taxonomy, order.office_id AS office_id FROM order, order_products, products, categories WHERE order.id = order_product.sales_id AND order_products.product_id = products.id AND product.category_id = categories.id AND (order.date BETWEEN :from AND :to) GROUP BY categories.taxonomy_id, order.office_id"; $stmt = $this->dbh->prepare($sql); $data = array( ':from' => $from, ':to' => $to ); $stmt->execute($data); $rec = $stmt->fetchAll(PDO::FETCH_ASSOC);

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

m.ts10806

2019/08/15 08:54

テーブル定義(CREATE TABLE文)とサンプルデータのINSERT文をご提示ください。 (table組で提示されているところを差し替えてもらったほうがいいですね) また、「とても時間がかかる」というのはどれくらいでしょうか。 それぞれのデータ件数もご提示ください。
m.ts10806

2019/08/15 09:06

CREATE TABLE文 と サンプルデータのINSERT文 です。 事情があって提示できないのでしたらそう書いていただけたらと。 要は実行するだけで同じ環境が作れるSQLを提示してほしいのです。 手元で再現確認もしたいですしね。
bws

2019/08/16 00:51

立て込んでしまい中途半端の追記になってしまって申し訳ありません。 CREATE文追記させていただきました。sqlのバックアップを仮想環境でそのまま使っている為、サンプルデータを使用していません。よろしくお願いします。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。