SQLite Part.10

1NAME IS NULL2012/08/16(木) 21:54:16.20ID:???
組み込み型データベース SQLite について語るスレッドです。

SQLite
http://www.sqlite.org/

・C/C++ API
 http://www.sqlite.org/c3ref/intro.html

・Syntax
 http://www.sqlite.org/lang.html

・Limits
 http://www.sqlite.org/limits.html

・Support
 http://www.sqlite.org/support.html

642NAME IS NULL2017/11/11(土) 21:51:16.84ID:???
>>641
ここに書いてある
https://sqlite.org/datatype3.html

643NAME IS NULL2017/11/11(土) 22:08:14.79ID:???
>>642
ありがとうございます
読んでみます

644NAME IS NULL2017/11/18(土) 01:48:42.44ID:F7zPqW66
>>636
元々実験バージョンだったはず

645NAME IS NULL2017/11/18(土) 12:09:57.30ID:???
なんのための実験?

646NAME IS NULL2017/11/24(金) 19:36:24.57ID:???
質問です。
ATTACHをすると異常に遅くなるのですが、これは最新バージョンで直ってますか?
或いは何らかの対策がありますか?

[環境]
PHP7.1.8+SQLite3.15.1(今年9月時点でのxampp最新版)
SQLite3.21.0のDLLをDLして差し替えたが動作せず

[状況]
・openよりもattachの方が優先順位が低いのか、追い越されている時がある。
・基本的にシーケンシャルにリクエストをしている。
(30秒ごとにキューに溜まったリクエストを順次送信する。
前リクエストの結果を受け取ってから0.1秒待って次リクエスト発行、これでシーケンシャル。
ただし30秒でキューが掃けない場合、上に被せるので、一時的に2並列になるときがある。)
・連続した場合、2回目以降は早い(ことが多い)。1回目は6秒程度、2回目以降は0.1-0.2秒程度で終了する。
・Timeout設定は5秒だが25秒かかっても問題なく正常終了する(タイムアウトしない)
・用途は掲示板で、リクエストはスレ立て/投稿/閲覧/スレ落ちを混ぜてテスト中。
・試行錯誤した結果、ATTACHしただけで遅いようだと判明した(ATTACHしたDBを触らずとも遅い)

[推定]
連続した場合には早いので、EXCLUSIVEロック待ちだと推定している。
ただしリクエストはほぼ全部シーケンシャルなので、本来はロック待ち自体がおかしい。
なお以下仕様のため、sqlite_masterの合成に時間がかかっているのか?とも思い、
全部mainをつけてみたが変化なし。(連続した場合に早いのでこの線もおかしいが)
> If the name of the table is unique across all attached databases and the main and temp databases, then the schema-name prefix is not required.
> http://www.sqlite.org/lang_attach.html

今のところ納得できる理由(原因)が見つかっておらず、対策が出来ていません。これについて、
対策方法(最新バージョンで直っているのならそれでよし)をご存知であればご教授ください。

最新版をPHPで試す方法はPHPのスレで聞いてみます。

647NAME IS NULL2017/11/25(土) 14:28:33.17ID:???
>>646
自己解決しました。

ATTACHの速度が対象DBのtable数にかなり依存するため、
ATTACHするとその場でsqlite_masterの合成をするのだと推定しました。
従って、ATTACH順を変更することにより改善できます。
今回は3つのDBを同時に扱うため、3C3の6通りでしかなく、速いのを選ぶことにしました。

なお、この実装がよいのかは若干疑問です。
通常はATTACH対象をさほどゴリゴリやらないので、
合成ではなく直列(カスケード)にして、その都度順に引いた方が速いと思われます。
或いは、合成/直列を選択するpragmaがあればよいのですが、これもないようです。
これらの問題のため、最新版等では改善している可能性もあります。(試せていません)

何か対応しようとしてくださった方が居ましたら、ありがとうございました。

648NAME IS NULL2017/11/25(土) 15:52:23.93ID:???
>>647
いやいやなになに

649NAME IS NULL2017/11/25(土) 16:20:09.78ID:???
>>647
ついでに続報を言うと、
ATTACHが遅くなるのはシステムキャッシュが無効(容量が足りない)時だけのようです。
合成自体は十分速く、
断片化したDB内のsqlite_masterのHDDからの読み出しに時間がかかっているようです。
だからまあ、現在(SQLite 3.15.1)の実装で問題ない、ということにもなりますが、、、

私の環境では、
RAMに十分空きがある(システムキャッシュにヒットする)場合には、
ATTACHは0.04-0.06秒程度で終了します。
RAMを使い尽くしている(システムキャッシュに十分な容量がない)場合には、
ATTACHだけで2-6秒程度かかり、これはVACUUM等で改善します。
また、ATTACHの順番を変えると何となく雰囲気が変わります。
(ただしこの結果は少し矛盾してますが)

650NAME IS NULL2017/11/25(土) 16:21:49.63ID:???
わざわざATTACHする理由は

651NAME IS NULL2017/11/25(土) 17:33:35.10ID:???
>>650
DB間のデータ転送をtransactionで括るため

652NAME IS NULL2017/11/25(土) 17:54:56.49ID:???
>>651
ATTACHするDBは違うホストにあるって事?
2相コミットのかわり?

653NAME IS NULL2017/11/25(土) 18:59:03.84ID:???
>>652
> 2相コミット
なんだこりゃ?Wiki読んだが何に使うのかよく分からん。
分散掲示板という意味なら面白いと思うし一部に待望されているが、俺が今作っているのはこれではない。
DBは同一ホストにある。

単にSQLiteの性能を出すために適宜DBを分割しているだけ。
というか、ロック単位がDBだから、平行させるためには分割するしかなく、そうしてるだけ。
(テーブル単位でロックできる他DBなら分割する意味はない)
例えばtech板なら、
「スレ本体(tech.live)」「スレヘッダのみ(全板共通)(tags.db)」「スレアーカイブ(tech.archived)」にしてあり、
スレ落ち時に
・tags.dbからヘッダを消去
・tech.live->tech.archivedにスレ内容転記
・tech.liveからスレを消去
する為にこれら3つをトランザクションで括っている。
この間に別板のスレの読み出しは、例えばprog板ならprog.liveだけで完結するのでブロックされない。
書き込みは全板共通のtags.dbによってブロックされてしまうが、これは仕様上致し方なし。
掲示板なので読み出し性能重視でこの設計にしている。

654NAME IS NULL2017/11/25(土) 19:07:59.44ID:???
>>653
2相コミットってSQLiteにあったのか
侮れんな

そんな面倒なことするのなら他のDBMSで良いんじゃね? とは思うけど
SQLiteじゃなきゃ駄目な理由があるんでしょうな

655NAME IS NULL2017/11/25(土) 19:18:27.38ID:???
>>654
複数DBのトランザクションという意味なら、それは追加されたらしい。
いつからかは知らん。

> SQLiteじゃなきゃ駄目な理由があるんでしょうな
共用鯖上で、PCの知識がほぼ無いadminでも扱える掲示板を目指している。
そのデプロイの都合上、PHP+SQLiteだ。
上位版はNodeで用意する予定だが、こちらもSQLiteになる。
それ以上の上位版は、他に既に色々あるからそっち使え、で行く。
興味あるのなら以下を読んでくれ。
https://meguca.org/g/2724701

656NAME IS NULL2017/11/25(土) 19:32:02.29ID:???
そういえばSQLiteのmainデータベースの名前を変える方法知らないか?
ググったけどなさそうなんだが。

具体的には>>647を試したコードがmainが3種類必要で結果的に3つコピペしてありうざい。
(live,tags,archiveにすれば共通化できるが、どれかをmainにしないといけない縛りのため)

657NAME IS NULL2017/11/25(土) 19:40:25.85ID:???
>>655
DBエンジンのインストールや設定って素人は難しく感じるようですね。
SQLiteは1ファイルで独立エンジン不要なのでローカルDBに使う分には良いですわ。

658NAME IS NULL2017/11/25(土) 19:42:22.24ID:???
>>656
データベースのファイル名を変えるだけでは?

659NAME IS NULL2017/11/25(土) 19:47:20.46ID:???
>>658
違う。
というか、調べた限り、ATTACH自体が新しい機能らしくて、そこまで整備されてない。
どの名前でもopenしたものはmainになるし、メモリ上のはtempになる。
それにATTACHしたものは自由に名前を付けられる、というか、つけないとsyntax上アウト。
で、mainの別名をつけられれば助かるんだが、、、
なお、tableやcolumnは別名を付けられる。

660NAME IS NULL2017/11/25(土) 19:54:47.58ID:???
>>659
あ、そう言う意味でしたか。
開発元に聞くか自分でソースコードを見るしか無さそうですが、
StackOverflowで聞けば教えて貰えるかも?
困った時はStackOverflow英語版!

661NAME IS NULL2017/11/25(土) 20:03:08.43ID:???
>>660
まあググっても出てこないし、多分まだ機能自体がないと諦めてるんだわ。
ありがとう。

662NAME IS NULL2017/11/25(土) 20:10:41.94ID:???
>>661
dummy db作って実際に使うDBは全部ATTACHでと言うのは駄目なの?
遅くはなるだろうけど。

663NAME IS NULL2017/11/25(土) 20:34:48.34ID:???
>>662
いやこれはソースコード上の美学の問題だから、それを構造まで広げるのはマズい。
どうしてもというのなら関数にすればいいだけだし、その方がマシ。
どのみち最終的にはコメントアウトで捨てるコードだし、
特にいいやり方がなければコピペで放置だ。

ただしtempにいったん受けた方が速い可能性があり、結果的にそれをやるかも。
具体的に言うと、sqlite_masterのマージで
少ない方を多い方にINSERTするわけだが、(どうやらこの判定はしている)
今のところliveに150、archivedは1000-10000スレ程度で運用する予定なので、
最低150のINSERTが発生して、これが0.05sかかっている。(ように見える)
tempで空テーブルを用意してやればこれが不要になる。
落ちるスレに150レスなら転記でINSERT150回必要であり、単純には倍速になる可能性がある。
というわけだ。

664NAME IS NULL2017/11/25(土) 21:11:41.89ID:???
>>663
旦那、ソースコードの美学なんてもんに拘ってたら、日本の薄汚いIT業界で食っていけませんぜwww

665NAME IS NULL2017/11/27(月) 12:31:20.51ID:???
日本の薄汚いIT業界でSQLiteなんて使わんだろ。
だいたいは自分の自主開発用とか趣味用だろ。
SQLiteでクライアントに納品してる奴とか保守してる奴とかいるの?
いるなら俺も雇ってくれw

666NAME IS NULL2017/11/27(月) 12:38:03.57ID:dl62vFEl
自主開発てなんかイヤラシイな

667NAME IS NULL2017/11/27(月) 12:56:06.29ID:???
イヤラシイのは自家発電

668NAME IS NULL2017/11/27(月) 13:09:39.99ID:???
>>665
居るよ!
SQLServer Express、mdbの代わりに使える。
Andoroidアプリならデフォでしょうし。

669NAME IS NULL2017/11/27(月) 14:45:54.11ID:???
SQLiteの爆速さと手軽さは中毒になるからな

670NAME IS NULL2017/11/27(月) 21:00:36.34ID:nKW4iMOq
こおゆう大げさな事をゆう奴を信用してはならん

671NAME IS NULL2017/11/27(月) 22:08:08.61ID:???
シングルユーザーで使う分には便利だよな
トランザクションとか自分で実装したくないし、遥かに信頼できる

672NAME IS NULL2017/11/27(月) 22:10:53.86ID:???
>>669
速いかは微妙じゃないか?

俺は結局、PRAGMA SYNCHRONOUS = OFF; PRAGMA JOURNAL_MODE = MEMORY;
を常用する羽目になっているが、これってどうなのよ?と思うし。
ただし作者の「ジャーナルにはHDDの2回転が必要で、それくらいはかかる」
というのもまた正しいわけだが。

673NAME IS NULL2017/11/27(月) 22:38:09.33ID:???
更新は遅いね

674NAME IS NULL2017/11/28(火) 01:19:55.49ID:???
いっぱいあるだろ。
何と言ってもPublicDomainってのが使いやすい。
使ってても言わなくていいし。

675NAME IS NULL2017/11/28(火) 19:58:13.47ID:???
ちょっと複雑なSQLを書けないところがNGかな。
副問い合わせとか。

それ以外はすんごくいい。

676NAME IS NULL2017/11/28(火) 21:11:17.44ID:???
服問い合わせ程度ならSQLite3でできるでしょ

677NAME IS NULL2017/11/28(火) 21:37:51.97ID:???
RIGHT OUTER JOIN、FULL OUTER JOIN が出来ないくらい?

678NAME IS NULL2017/11/29(水) 14:42:34.87ID:???
>>673
AutoCommitしてんじゃねーの?

6796752017/11/30(木) 05:52:18.47ID:???
>>676, 677
え?ほんと?
おぼろげな記憶だけど、

SELECT ...
FROM ...
WHERE xxx IN (SELECT...)

とかできなかったような・・・

680NAME IS NULL2017/11/30(木) 06:49:33.48ID:???
こういう人はなんでググったり試したりしてからレスしようとしないんだろう...
https://www.sqlite.org/lang_expr.html#subq

お前さんのおぼろげな記憶とやらに興味はないし

681NAME IS NULL2017/11/30(木) 07:15:36.60ID:???
>>679
そのクエリならできる。まさに俺が現在使っているし。

682NAME IS NULL2017/11/30(木) 08:35:09.19ID:???
>>680
敵性言語で書かれている情報など読みません。

683NAME IS NULL2017/11/30(木) 09:14:35.55ID:???
>>679
余裕で書けるのだが、何で出来ないと思ったのか聞いてみたい

684NAME IS NULL2017/11/30(木) 09:35:48.26ID:???
>>683
してないから

685NAME IS NULL2017/11/30(木) 12:06:22.71ID:???
一回試してタイプミスで文法エラーが出たのに
できないと思い込むケースはあるかもね
できないだろう、という先入観があるとどうしてもね

686NAME IS NULL2017/11/30(木) 12:49:33.88ID:???
>>682
じゃあ敵が書いたプログラムなんか使うなよ w

6876752017/11/30(木) 18:22:37.58ID:???
かなり前のことなので、残念ながら具体的なクエリは忘れてしまいました。
ただ、俺のメインはPostgreSQLなので、それに比べてSQLiteはSQLを書く
自由度がかなり劣っている印象を受けたのは事実。

思い違いかもしれないので、また今度触ってみるよ。
誤った知識でSQLiteのNG情報を流布しては申し訳ないしね。

688NAME IS NULL2017/11/30(木) 19:42:18.44ID:ATTMxwZh
そんなに影響力ないから気にすんなw

689NAME IS NULL2017/12/29(金) 11:06:14.25ID:dtNZwIie
誰でも簡単にパソコン1台で稼げる方法など
参考までに、
⇒ 『宮本のゴウリエセレレ』 というブログで見ることができるらしいです。

グーグル検索⇒『宮本のゴウリエセレレ』

M9UL2UMY6S

690NAME IS NULL2017/12/29(金) 17:29:28.25ID:???

691NAME IS NULL2018/01/23(火) 22:27:43.42ID:Wf3T2feU

692NAME IS NULL2018/02/14(水) 13:24:45.81ID:???
☆ 日本の、改憲をしましょう。現在、衆議員と参議院の両院で、
改憲議員が3分の2を超えております。『憲法改正国民投票法』、
でググってみてください。国会の発議はすでに可能です。
平和は勝ち取るものです。お願い致します。☆☆

新着レスの表示
レスを投稿する