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

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

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

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

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

Q&A

5回答

934閲覧

1.7GBのmysql読み込み

rutawaru

総合スコア22

MySQL

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

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

0グッド

1クリップ

投稿2018/09/22 23:17

3千万行以上あるmysqlからselectしたいのですが、下記のメッセージが出て読み込めません。

Fatal error: Allowed memory size of 2147483648 bytes exhausted (tried to allocate 211812368 bytes) in

環境はMAMPローカル環境でGoogle Chromeを使って表示しています。

「ini_set('memory_limit', '2G');」はやってみました。

やりたいことは300個程のデータを3千万行のデータから合うデータを探しすことなので最初のselect時に全部のデータを読み込まず、条件に合うデータだけを読み込めば良いのかと思い、色々やりましたがうまく出来ませんでした。

このエラーを回避するにはどうすればいいでしょうか。

php

1<?php 2require_once '../vendor/autoload.php'; 3use Cake\Chronos\Chronos; 4ini_set('memory_limit', '2G'); 5 6$UserName = 'root'; 7$PassWord = 'root'; 8 9$Database = new PDO('mysql:host=localhost;dbname=Encryption_Currency;charset=UTF8;', $UserName, $PassWord); 10$Database->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 11 12try { 13$sql = "SELECT * FROM `bitflyerJPY`"; 14$statement = $Database->query($sql); 15// $statement->execute(); 16$records = $statement->fetchAll(PDO::FETCH_ASSOC); 17$statement = null; 18$Database = null; 19} catch (PDOException $error){ 20echo $error->getMessage(); 21exit; 22}; 23 24$bittrexFileName = "fullOrders_Ecxel.csv"; 25$bittrex = []; 26$bittrexTime = []; 27$bittrexUnixTime = []; 28 29function READ_CSV($file) { 30 if (pathinfo($file, PATHINFO_EXTENSION) === "csv") { 31 try { 32 $FileObject = new SplFileObject($file); 33 } catch (Exception $e) { 34 echo $e->getMessage(); 35 } 36 $FileObject->setFlags( 37 SplFileObject::READ_CSV 38 ); 39 foreach ($FileObject as $line) { 40 $array[] = $line; 41 } 42 return $array; 43 44 } else { 45 echo "CSVファイルではありません。"; 46 } 47} 48 49function CONVERT_INT_BY_MAP ($stringarray) { 50 $Int = intval($stringarray); 51 return $Int; 52} 53 54function CONVERT_UNIX ($timearray){ 55 $Time = new Chronos($timearray); 56 $UnixTime = $Time->timestamp; 57 return $UnixTime; 58} 59 60$bittrex = READ_CSV($bittrexFileName); 61 62for ($k = 0; $k < count($bittrex[0]); $k++){ 63 $key = $bittrex[0][$k]; 64 for ($i = 1; $i < count($bittrex)-1; $i++){ 65 $bittrexWithkey[$i][$key] = $bittrex[$i][$k]; 66 } 67} 68 69$bittrexTime = array_column($bittrexWithkey, 'Closed'); 70 71$bittrexUnixTime = array_map("CONVERT_UNIX", $bittrexTime); 72 73 74$BTCPrice =[]; 75for ($i = 0; $i < count($bittrexUnixTime); $i++){ 76 $Ikaarray = []; 77 for ($j = 0; $j < count($records); $j++) { 78 if ($records[$j]["Time"] <= $bittrexUnixTime[$i]) { 79 array_push($Ikaarray, $records[$j]["Time"]); 80 } 81 } 82 $BTCPrice[$i]["Time"] = $bittrexUnixTime[$i]; 83 $BTCPrice[$i]["Price"] = $records[count($Ikaarray)-1]["Price"]; 84} 85 86 87 88$filepath = "bittrexBTCJPY.csv"; 89 90try { 91 $FileObject = new SplFileObject($filepath, "w"); 92} catch (Exception $e) { 93 echo $e->getMessage(); 94} 95 96foreach ($BTCPrice as $row) { 97 $FileObject->fputcsv($row); 98} 99

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

全て必要でないならwhereで絞り込めば良いと思うのですがどうやって絞りこもうと込もうとしてますか?
また2Gメモリ確保は現実的に難しいと思います。
それ以上かかってるからそのサイズでのメモリーエラーが出ていますが、実際に必要なメモリーはデータ量だけではないのでマシンへの負荷も考えると、
SELECT時点で絞り込むしかないかなと。
「300個程のデータを3千万行のデータから合うデータ」がどういう条件か質問内容からは読み取れなかったので、そこは提示いただくか考えてもらうしかありませんが。

投稿2018/09/22 23:59

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rutawaru

2018/09/23 04:11

$aaarr = []; $biTimearray = [1509493559, 1514880621, 1505338168]; for ($i = 0; $i < count($biTimearray)+1; $i++) { $biTime = $biTimearray[$i]; try { $sql = "SELECT * FROM `bitflyerJPY` WHERE `Time` <= {$biTime} ORDER BY `Time` DESC LIMIT 1"; $statement = $Database->prepare($sql); $statement->execute(); $records = $statement->fetchAll(PDO::FETCH_ASSOC); array_push($aaarr, $records); $statement = null; $Database = null; } catch (PDOException $error){ echo $error->getMessage(); exit; }; }
rutawaru

2018/09/23 04:12

ご回答ありがとうございます。 こうゆう風にforで回そうと思ったのですが、出来ません。 SELECTでforは使えませんか?
m.ts10806

2018/09/23 04:31 編集

いえ。取得するデータ自体を絞りこんで込んで取得することでphpのforは不要となるようにすべきです。 何度もDBアクセスすることでその分、負荷が高まります。一度のSELECTで全てのデータを取得してください。 これって、どういうデータを取ろうとしてますか?
m.ts10806

2018/09/23 07:21

もし「biTimearrayで設定している3つの時間以前」を取得であればor条件でつなげば取得できそうに思います。 SELECT * FROM `bitflyerJPY` WHERE `Time` <= 1509493559 or `Time` <= 1514880621 or `Time` <= 1505338168 ORDER BY `Time` DESC LIMIT 1 もし、「3つだけじゃなく不定数あるんだ」ということでしたら 配列に入れたうえで、上記のor条件の形を作って1つのSELECTにすればいいだけですし。 いずれにしても何回も接続して何回も実行するのはメモリの無駄遣いになります。
guest

0

どんなテーブルを使っているのかがわかるように、質問にCREATE TABLE を追記してください。

やりたいことは300個程のデータを3千万行のデータから合うデータを探しすことなので最初のselect時に全部のデータを読み込まず、条件に合うデータだけを読み込めば良いのかと思い、色々やりましたがうまく出来ませんでした。

3千万件のデータから300件程度をどんな条件で取り出したいのかも質問に明記してください。

大型倉庫の荷物を全部外に出してその中から必要なものを取り出す、なんて無駄なことはしませんよね。普通必要な荷物だけ運び出します。
データーベースも同じです。

投稿2018/09/23 08:41

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

fetchAllでメモリ不足になっていると思うので、fetchでループして同等の処理に変えてみました。
たぶんこれで動くと思います。

php

1<?php 2 3require_once '../vendor/autoload.php'; 4use Cake\Chronos\Chronos; 5 6function READ_CSV($file) { 7 $array = []; 8 if (pathinfo($file, PATHINFO_EXTENSION) === "csv") { 9 try { 10 $FileObject = new SplFileObject($file); 11 } catch (Exception $e) { 12 echo $e->getMessage(); 13 } 14 $FileObject->setFlags(SplFileObject::READ_CSV); 15 foreach ($FileObject as $line) $array[] = $line; 16 } else { 17 echo "CSVファイルではありません。"; 18 } 19 return $array; 20} 21function CONVERT_UNIX($timearray) { 22 $Time = new Chronos($timearray); 23 $UnixTime = $Time->timestamp; 24 return $UnixTime; 25} 26 27$bittrexFileName = "fullOrders_Ecxel.csv"; 28$bittrex = READ_CSV($bittrexFileName); 29$bittrexWithkey = []; 30for ($k = 0; $k < count($bittrex[0]); $k++) { 31 $key = $bittrex[0][$k]; 32 for ($i = 1; $i < count($bittrex) - 1; $i++) { 33 $bittrexWithkey[$i][$key] = $bittrex[$i][$k]; 34 } 35} 36$bittrexTime = array_column($bittrexWithkey, 'Closed'); 37$bittrexUnixTime = array_map("CONVERT_UNIX", $bittrexTime); 38 39$BTCPrice =[]; 40foreach ($bittrexUnixTime as $time) $BTCPrice[] = array('Time' => $time, 'Price' => null); 41 42 43$UserName = 'root'; 44$PassWord = 'root'; 45$Database = new PDO('mysql:host=localhost;dbname=Encryption_Currency;charset=UTF8;', $UserName, $PassWord); 46$Database->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 47try { 48 $sql = "SELECT * FROM `bitflyerJPY`"; 49 $statement = $Database->query($sql); 50 while ($record = $statement->fetch(PDO::FETCH_ASSOC)) { 51 for ($i = 0; $i < count($bittrexUnixTime); $i++) { 52 if ($record['Time'] <= $bittrexUnixTime[$i]) $BTCPrice[$i]['Price'] = $records['Price']; 53 } 54 } 55} catch (PDOException $error){ 56 echo $error->getMessage(); 57 exit; 58}; 59 60 61$filepath = "bittrexBTCJPY.csv"; 62try { 63 $FileObject = new SplFileObject($filepath, "w"); 64} catch (Exception $e) { 65 echo $e->getMessage(); 66} 67 68foreach ($BTCPrice as $row) { 69 $FileObject->fputcsv($row); 70} 71

投稿2018/09/23 08:44

kaba

総合スコア314

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

この回答は見当はずれの内容でした^^;失礼

そもそもコマンドラインから mysql コマンドで実行できるのでしょうか?

もし実行可能なのであれば、php 内で実行せず、直接 mysql コマンドで抽出しファイルに書き出すようにして、そのファイルを監視するような仕組みにしてみては?

投稿2018/09/23 04:33

編集2018/09/23 09:33
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

参考までに
つ Fatal error: Allowed memory size of エラーの対応【PHP】

timestampで過去のデータを切り捨てる方法もあるようですが・・・
参考:ビットコインのヒストリカルデータ(1分毎)の取得

投稿2018/09/22 23:56

編集2018/09/23 00:57
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問