MySQLの範囲検索でレコードが多すぎるとフルテーブルスキャンになってしまう現象
created_atが何月何日から何月何日
のレコードをSELECTする場合に、ある量を超えるとEXPLAIN上ではフルテーブルスキャンの判定になってしまったのでどうしてなのか実験してみました。
実験は次のような環境で行いました。
OS: OS X El Capitan 10.11.3 CPU: 1.2 GHz Intel Core M Memory: 8GB 1600 MHz DDR3 $ mysql --version mysql Ver 14.14 Distrib 5.6.28, for osx10.11 (x86_64) using EditLine wrapper
準備
まず、range_test
という名前のテーブルを作ります。
int型、bigint型、datetime型のカラムを作成して、それぞれ比較してみました。
カラム名 | 型 | 取りうる値の範囲 |
---|---|---|
id | bigint unsigned (PK) | 1 〜 5,000,000 |
int_col | int | 0 〜 10,000 |
bigint_col | bigint | 1 〜 9,999,999 |
datetime_col | datetime | 2000-01-01 00:00:00 〜3000-01-08 00:00:00 |
インデックスが効くかどうかの実験なので、それぞれのカラムにインデックスを貼っておきます。
mysql> create database db_range_test; Query OK, 1 row affected (0.03 sec) mysql> use db_range_test; Database changed mysql> create table range_test ( -> id bigint unsigned not null auto_increment, -> int_col int, -> bigint_col bigint, -> datetime_col datetime, -> primary key (id), -> key idx_int (int_col), -> key idx_bigint (bigint_col), -> key idx_datetime (datetime_col) -> ) engine=InnoDB default charset utf8; Query OK, 0 rows affected (0.11 sec)
こんな感じのスクリプトを書いて、MySQLに5,000,000件のダミーデータをINSERTします。
require 'sequel' require 'mysql2' require 'active_support' require 'active_support/core_ext' DB = Sequel.connect('mysql2://root@localhost/db_range_test') (1..5_000_000).each do |i| int_r = rand(0..10_000) big_r = rand(0..10_000_000) dat_r = rand(0..1_000) DB[:range_test].insert( int_col: int_r, bigint_col: big_r, datetime_col: DateTime.new(2000, 1, 1).since(dat_r.years) ) end
5,000,000件入りました。 SELECT COUNT(*)に5秒弱かかるとは。。。
mysql> select count(*) from range_test; +----------+ | count(*) | +----------+ | 5000000 | +----------+ 1 row in set (4.96 sec) mysql> select * from range_test limit 10; +----+---------+------------+---------------------+ | id | int_col | bigint_col | datetime_col | +----+---------+------------+---------------------+ | 1 | 7521 | 8840230 | 2988-01-08 00:00:00 | | 2 | 8951 | 617956 | 2454-01-03 12:00:00 | | 3 | 4677 | 4115021 | 2111-01-01 18:00:00 | | 4 | 8235 | 7919478 | 2906-01-07 12:00:00 | | 5 | 5710 | 2487144 | 2958-01-07 12:00:00 | | 6 | 9313 | 3383 | 2805-01-06 06:00:00 | | 7 | 3602 | 9241458 | 2336-01-04 00:00:00 | | 8 | 8950 | 8957220 | 2970-01-07 12:00:00 | | 9 | 9052 | 731523 | 2865-01-06 06:00:00 | | 10 | 5988 | 5204737 | 2121-01-01 06:00:00 | +----+---------+------------+---------------------+ 10 rows in set (0.00 sec)
実験
int
mysql> explain select * from range_test where 0 <= int_col and int_col <= 7; +----+-------------+------------+-------+---------------+---------+---------+------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+---------+---------+------+------+-----------------------+ | 1 | SIMPLE | range_test | range | idx_int | idx_int | 5 | NULL | 3849 | Using index condition | +----+-------------+------------+-------+---------------+---------+---------+------+------+-----------------------+ 1 row in set (0.01 sec) mysql> select count(*) from range_test where 0 <= int_col and int_col <= 7; +----------+ | count(*) | +----------+ | 3850 | +----------+ 1 row in set (0.00 sec) mysql> explain select * from range_test where 0 <= int_col and int_col <= 8; +----+-------------+------------+-------+---------------+---------+---------+------+------+----------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+---------+---------+------+------+----------------------------------+ | 1 | SIMPLE | range_test | range | idx_int | idx_int | 5 | NULL | 4355 | Using index condition; Using MRR | +----+-------------+------------+-------+---------------+---------+---------+------+------+----------------------------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= int_col and int_col <= 8; +----------+ | count(*) | +----------+ | 4356 | +----------+ 1 row in set (0.01 sec) mysql> explain select * from range_test where 0 <= int_col and int_col <= 1009; +----+-------------+------------+-------+---------------+---------+---------+------+--------+----------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+---------+---------+------+--------+----------------------------------+ | 1 | SIMPLE | range_test | range | idx_int | idx_int | 5 | NULL | 929646 | Using index condition; Using MRR | +----+-------------+------------+-------+---------------+---------+---------+------+--------+----------------------------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= int_col and int_col <= 1009; +----------+ | count(*) | +----------+ | 505016 | +----------+ 1 row in set (0.20 sec) mysql> explain select * from range_test where 0 <= int_col and int_col <= 1010; +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ | 1 | SIMPLE | range_test | ALL | idx_int | NULL | NULL | NULL | 4986946 | Using where | +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= int_col and int_col <= 1010; +----------+ | count(*) | +----------+ | 505547 | +----------+ 1 row in set (0.15 sec)
途中でExtraにUsing MRR
というものが出るようになったのですが、どうやらMySQL 5.6から入ったMulti-Range Readというものがあるらしい。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.2.1.13 Multi-Range Read の最適化
検索条件に合致するレコード数 | 全レコード数から占める割合 | type | Extra |
---|---|---|---|
〜 3,850 | 〜 0.0770% | range | Using index condition |
4,356 〜 505,016 | 0.0871%〜10.1% | range | Using index condition; Using MRR |
505,547 〜 | 10.1% 〜 | ALL | Using where |
bitint
mysql> explain select * from range_test where 0 <= bigint_col and bigint_col <= 7843; +----+-------------+------------+-------+---------------+------------+---------+------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------------+---------+------+------+-----------------------+ | 1 | SIMPLE | range_test | range | idx_bigint | idx_bigint | 9 | NULL | 3989 | Using index condition | +----+-------------+------------+-------+---------------+------------+---------+------+------+-----------------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= bigint_col and bigint_col <= 7843; +----------+ | count(*) | +----------+ | 3990 | +----------+ 1 row in set (0.00 sec) mysql> explain select * from range_test where 0 <= bigint_col and bigint_col <= 7844; +----+-------------+------------+-------+---------------+------------+---------+------+------+----------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------------+---------+------+------+----------------------------------+ | 1 | SIMPLE | range_test | range | idx_bigint | idx_bigint | 9 | NULL | 3990 | Using index condition; Using MRR | +----+-------------+------------+-------+---------------+------------+---------+------+------+----------------------------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= bigint_col and bigint_col <= 7844; +----------+ | count(*) | +----------+ | 3991 | +----------+ 1 row in set (0.00 sec) mysql> explain select * from range_test where 0 <= bigint_col and bigint_col <= 898823; +----+-------------+------------+-------+---------------+------------+---------+------+--------+----------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+------------+---------+------+--------+----------------------------------+ | 1 | SIMPLE | range_test | range | idx_bigint | idx_bigint | 9 | NULL | 982422 | Using index condition; Using MRR | +----+-------------+------------+-------+---------------+------------+---------+------+--------+----------------------------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= bigint_col and bigint_col <= 898823; +----------+ | count(*) | +----------+ | 450211 | +----------+ 1 row in set (0.18 sec) mysql> explain select * from range_test where 0 <= bigint_col and bigint_col <= 898824; +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ | 1 | SIMPLE | range_test | ALL | idx_bigint | NULL | NULL | NULL | 4986946 | Using where | +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where 0 <= bigint_col and bigint_col <= 898824; +----------+ | count(*) | +----------+ | 450212 | +----------+ 1 row in set (0.13 sec)
検索条件に合致するレコード数 | 全レコード数から占める割合 | type | Extra |
---|---|---|---|
〜 3,990 | 〜 0.0798% | range | Using index condition |
3,991 〜 450,211 | 0.0798% 〜 9.00% | range | Using index condition; Using MRR |
450,212 〜 | 9.00% 〜 | ALL | Using where |
datetime
mysql> explain select * from range_test where '2000-01-01 00:00:00' <= datetime_col and datetime_col <= '2079-01-01 00:00:00'; +----+-------------+------------+-------+---------------+--------------+---------+------+--------+----------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+--------------+---------+------+--------+----------------------------------+ | 1 | SIMPLE | range_test | range | idx_datetime | idx_datetime | 6 | NULL | 905046 | Using index condition; Using MRR | +----+-------------+------------+-------+---------------+--------------+---------+------+--------+----------------------------------+ 1 row in set (0.01 sec) mysql> select count(*) from range_test where '2000-01-01 00:00:00' <= datetime_col and datetime_col <= '2079-01-01 00:00:00'; +----------+ | count(*) | +----------+ | 398998 | +----------+ 1 row in set (0.18 sec) mysql> explain select * from range_test where '2000-01-01 00:00:00' <= datetime_col and datetime_col <= '2080-01-01 00:00:00'; +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ | 1 | SIMPLE | range_test | ALL | idx_datetime | NULL | NULL | NULL | 4986946 | Using where | +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+ 1 row in set (0.00 sec) mysql> select count(*) from range_test where '2000-01-01 00:00:00' <= datetime_col and datetime_col <= '2080-01-01 00:00:00'; +----------+ | count(*) | +----------+ | 404030 | +----------+ 1 row in set (0.16 sec)
検索条件に合致するレコード数 | 全レコード数から占める割合 | type | Extra |
---|---|---|---|
〜 398,998 | 〜 7.98% | range | Using index condition; Using MRR |
404,030 〜 | 8.08% 〜 | ALL | Using where |
単純な実験ですが、全レコードの約9%より多いレコードを取得しようとすると、EXPLAIN上ではフルテーブルスキャンの戦略が選ばれてしまうようでした。
フルテーブルスキャンの戦略が選ばれたクエリを打ってみても、あまり実行時間に変化がない(0.02 sec前後)ので、本当にフルテーブルスキャンしているのかが気になりました。
途中まで実験してから思ったのですが、MySQLのパラメータをいじったら変化が出るのではないかとかも考えたのですが、追いきれなかったのでまた今度。。。
追記
http://spring-mt.hatenablog.com/entry/2016/02/18/010911
optimizer_traceなんてものがあるのですね…!
railsへの執着はもはや煩悩の域であり、開発者一同は瞑想したほうがいいと思います。 というチームでしたがISUCON5予選ダメでした #isucon
一昨年、去年と出てて、今年が3回目のISUCONでした。 去年までは学生枠だったのですが、今年から社会人になってしまったので一般枠になってしまいました。
今年も、去年と同じ id:cnosuke さんと id:k0kubun さんと出ました。
競技中についてはk0kubunさんが大体全部書いてくれました → http://k0kubun.hatenablog.com/entry/2015/09/27/225243
上の記事のとおりですが、k0kubunさんががアプリケーション周りを全体的に、cnosukeさんがnginxとかredis周りとか、自分がMySQL周りを、なんとなく3人で分担してました。
したこと
ひたすらボトルネックを探してそこを潰す、潰したらまた探して潰す、、、という感じの流れでした。 k0kubunさんの記事に書いてあるようにジワジワとスコアが上がっていくのは見ていて楽しかったです。
New Relicとrack-lineprofがひたすら便利でした。 あと、cnosukeさんが書いたnginxのログからアクセス頻度見るツールとか使ってました。
自分はMySQL周りを見ていたので、slow queryを吐き出させてそこから頻出クエリと時間がかかっているクエリを探して、インデックス貼ったりクエリ改善できるかを模索したりしてました。 slow queryを吐き出す設定が何故かファイルに書いても動かなかったので、こんな感じで直接打ってました(適当)。
mysql> SET GLOBAL slow_query_log = 1; # オフにするときは0にする mysql> SET GLOBAL slow_query_log_file = /var/log/mysql/slow.log; mysql> SET GLOBAL long_query_time = 0;
以前は適当に手当たり次第「これ直りそうじゃない?」みたいなものを見つけて改善しようとしてましたが、 それだと当たり前ですが効果が全然出ないことが多いので、「推測するな、計測せよ」がメチャメチャ大切だと思いました。
結局最終的にスコア11045
で終わりましたが、終了直前にベンチ回したのでもしかしたら若干違うかもです。
足切りラインが14000くらいだったので、もうちょっとで本戦にいけるかもしれなかったので悔しいです(ヽ´ω`)
今年は残念でしたが、また来年開催されましたらぜひ参加したいです!!!
JavaのライブラリのテストをJRuby+minitestで書く
お前は何と戦っているんだ感が半端ないですが、タイトルの通りJavaで書いたライブラリのテストをJRuby+minitestで書いてみました。
テストを書く対象のライブラリは、よくある(?)行列演算を行うやつです。
例としてMyMatrixLib.jar (net.rkmathi.lib.MyMatrixLib)
という名前にしてみます。
JRuby, minitestのインストール
rbenvを使っているので、それ経由で入れました。
$ rbenv install -l | grep jruby ... jruby-1.7.16 jruby-1.7.16.1 jruby-9.0.0.0-dev jruby-9000-dev ...
jruby-1.7.16.1にしました。
$ rbenv install jruby-1.7.16.1
テスト書くディレクトリに移動して、rbenv local
でjrubyを使うようにします。
$ cd /path/to/test_directory $ rbenv local jruby-1.7.16.1 $ rbenv rehash $ jruby --version jruby 1.7.16.1 (1.9.3p392) 2014-10-28 4e93f31 on Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17 +jit [darwin-x86_64]
minitestのインストールをします。
$ jruby -S gem install minitest
ライブラリのJARを持ってくる
$ cd /path/to/test_directory $ cp /path/to/MyMatrixLib.jar .
JRuby+minitestでテストを書く
とりあえず、get()とplus()とminus()のテストを書いてみるとこうなります。
require 'minitest' require 'minitest/autorun' require 'java' require_relative './MyMatrixLib.jar' import 'net.rkmathi.lib.MyMatrixLib' class TestMyMatrixLib < Minitest::Test def setup @d1 = rand(1000.0) @d2 = rand(1000.0) @m1 = MyMatrixLib.new(3, 2, @d1) # 3x2ですべての要素が@d1の行列を生成 @m2 = MyMatrixLib.new(3, 2, @d2) # 3x2ですべての要素が@d2の行列を生成 end # get(r, c) => double: 行列のr行c列目の要素を取得 def test_get each_assert_get @m1, @d1 each_assert_get @m2, @d2 end # plus(matrix) => MyMatrix: 行列のそれぞれの要素を足した行列を生成 def test_plus d_res = @d1 + @d2 m_res = @m1.plus(@m2) # @m1と@m2のそれぞれの要素を足した結果の行列 each_assert_get m_res, d_res end # minus(matrix) => MyMatrix: 行列のそれぞれの要素を引いた行列を生成 def test_minus d_res = @d1 - @d2 m_res = @m1.minus(@m2) # @m1と@m2のそれぞれの要素を引いた結果の行列 each_assert_get m_res, d_res end private # 行列の各要素をそれぞれgetするのが面倒なのでメソッド化 def each_assert_get(m, d) for r in 0...m.get_row_dimension do for c in 0...m.get_column_dimension do assert_equal m.get(r, c), d end end end ... end
と、こんな感じで書くことができます。
ちなみにJUnitだと...
public class MyMatrixLibTest { @Before public void setUp() throws Exception { MyMatrixLib d1 = Math.random() * 1000.0; MyMatrixLib d2 = Math.random() * 1000.0; MyMatrixLib m1 = new MyMatrixLib(3, 2, d1); MyMatrixLib m2 = new MyMatrixLib(3, 2, d2); } @Test public void testGet() { eachAssertGet(m1, d1); eachAssertGet(m2, d2); } @Test public void testPlus() { double d_res = d1 + d2; MyMatrixLib m_res = m1.plus(m2); eachAssertGet(m_res, d_res); } @Test public void testMinus() { double d_res = d1 - d2; MyMatrixLib m_res = m1.minus(m2); eachAssertGet(m_res, d_res); } private void eachAssertGet(MyLibMatrix m, double d) { for (int row = 0; row < m.getRowDimension(); row++) { for (int column = 0; column < m.getRowDimension(); column ++) { assertEquals(m.get(row, column), d); } } } }
簡単な演算のテスト部分しか比較しませんでしたが、書いてて楽には思えました。
ですが、JRubyを書いていると文法とか変数の型をミスった時に吐かれる例外がよくわからないことになることもあるので、わざわざJRubyでテスト書くのは微妙かも...
VPS上にSoftEther VPN ServerをセットアップしてOS Xからつなぐ
HDD容量を少なくすればめちゃ安いVPS( http://www.idcf.jp/cloud/ )を教えてもらったので、ここにSoftEtherVPN Serverをセットアップしてみました。
ちなみに、仮想マシンを作成するときに「テンプレート」からだとHDD容量が最低15GBなので540円/月ですが、「ISO」から作るようにすると最低1GBから選べるようになります。例えば5GBにすれば324円/月で済みます。
ポートの設定
VPSのコントロールパネル側でファイアウォールの設定があるので、
のポートを開けておきます。
SoftEther VPNのダウンロード
SoftEther ダウンロードセンターから、SoftEther VPN (Freeware)
→SoftEther VPN Server
→Linux
→Intel x64 / AMD64 (64bit)
を選んで、最新ビルドのリンクのアドレスをメモっておきます。
あとで、OSをインストールしたらこのリンクから引っ張ってきます。
OSのインストールとファイルの配置
適当に、Ubuntu Server 14.04 amd64
をインストールしておきました。
### 必要なパッケージのインストール ~$ sudo aptitude update ~$ sudo aptitude upgrade ~$ sudo aptitude install build-essential sysv-rc-conf ### さっきのリンクからダウンロード ~$ wget http://jp.softether-download.com/files/XXX/softether-vpnserver-XXX-linux-x64-64bit.tar.gz ~$ tar xvf softether-vpnserver-XXX-linux-x64-64bit.tar.gz ~$ cd vpnserver ### 確認したら、1でAcceptしてmake ~/vpnserver$ make 1 1 1 ### vpnserverのパーミッションを変更 ~/vpnserver$ chmod 600 * ~/vpnserver$ chmod 700 vpncmd vpnserver ~/vpnserver$ cd ../ ~$ sudo mv vpnserver /usr/local/ ~$ sudo chown -R root:root /usr/local/vpnserver ~$ cd /usr/local/vpnserver ### 動作確認 /usr/local/vpnserver$ sudo ./vpncmd 3 check exit /usr/local/vpnserver$ cd ### initスクリプトを書いて、パーミッションを755にしておく ~$ sudo chmod 755 /etc/init.d/vpnserver ~$ sudo cat /etc/init.d/vpnserver #!/bin/sh # description: SoftEther VPN Server DAEMON=/usr/local/vpnserver/vpnserver LOCK=/var/lock/vpnserver test -x $DAEMON || exit 0 case "$1" in start) $DAEMON start touch $LOCK ;; stop) $DAEMON stop rm $LOCK ;; restart) $DAEMON stop sleep 3 $DAEMON start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit 0 ### sysv-rc-confでvpnserverの2,3,4,5にチェック ~$ sudo sysv-rc-conf ... ### 再起動 ~$ sudo reboot
SoftEther VPN Serverのセットアップ
~$ cd /usr/local/vpnserver /usr/local/vpnserver$ sudo ./vpncmd 1 localhost (Enter) ### VPN Serverのパスワードを設定 VPN Server> ServerPasswordSet (パスワードを設定) ### 仮想ハブを作成 ここではVPNHUBという名前にしてある VPN Server> HubCreate Name of Virtual Hub to be created: VPNHUB ### VPNHUBに切り替え VPN Server> Hub VPNHUB ### SecureNatを有効に VPN Server/VPNHUB> SecureNatEnable ### ユーザを作成 ここではvpnという名前にしてある VPN Server/VPNHUB> UserCreate vpn (Enter) (Enter) (Enter) ### 上で作ったvpnユーザのパスワードを設定 VPN Server/VPNHUB> UserPasswordSet vpn (VPN User Password) (VPN User Password) ### IPSecを有効に VPN Server/VPNHUB> IPSecEnable Enable L2TP over IPsec Server Function (yes / no): yes Enable Raw L2TP Server Function (yes / no): no Enable EtherIP / L2TPv3 over IPsec Server Function (yes / no): no Pre Shared Key for IPsec (Recommended: 9 letters at maximum): (IPsec Secret Key) Default Virtual HUB in a case of omitting the HUB on the Username: VPNHUB VPN Server/VPNHUB> exit $ sudo service vpnserver restart
OS X(クライアント)側の設定
システム環境設定
→ネットワーク
→左下の+マークで追加
↑画像のサーバアドレス
とアカウント名
を埋めたら、下にある認証設定…
をクリック
ユーザ認証 パスワード
に(VPN User Password)を、コンピュータ認証 共有シークレット
に(IPsec Key)を入力
これで接続ができるように(┐「ε:)
GitLabでMaven Repositoryを作ってGradleから使う
研究室でJavaのプログラムを書いているのですが、ライブラリを研究室内で共有するときにMaven Repositoryを立てたらいいのではないかと思ったので、GitLab上で使うようにしました。
想定するプログラム
- ライブラリ(MyLib)
- MyLibを使用するプログラム(MyProgram)
MyLibのbuild.gradle
apply plugin: 'idea' apply plugin: 'java' apply plugin: 'maven' def defaultEncoding = 'UTF-8' [compileJava, compileTestJava]*.options*.encoding = defaultEncoding sourceCompatibility = 1.7 targetCompatibility = 1.7 group = 'net.rkmathi' archivesBaseName = 'mylib' version = '1.0.0' repositories { maven { url System.getenv('HOME') + '/.m2/repository' } mavenCentral() } dependencies { testCompile 'junit:junit:4.11' } uploadArchives.repositories.mavenDeployer { repository(url: "file:${projectDir}/maven") }
これでgradle uploadArchives
を実行すると、maven
ディレクトリ以下に出力されます。
- uploadArchivesで出力したら、gitリポジトリにそのディレクトリも追加して、GitLabへプッシュします。
MyProgramのbuild.gradle
apply plugin: 'idea' apply plugin: 'java' apply plugin: 'maven' def defaultEncoding = 'UTF-8' [compileJava, compileTestJava]*.options*.encoding = defaultEncoding sourceCompatibility = 1.7 targetCompatibility = 1.7 group = 'net.rkmathi' archivesBaseName = 'myprogram' version = '1.0.0' repositories { maven { url System.getenv('HOME') + '/.m2/repository' } maven { url 'http://<<GitLab Address>>/<<User Name>>/mylib/raw/master/maven' } mavenCentral() } dependencies { compile 'net.rkmathi:mylib:1.0.0' testCompile 'junit:junit:4.11' } uploadArchives.repositories.mavenDeployer { repository(url: "file:${projectDir}/maven") }
これで、MyProgramからMyLibを使うことができました。
http://<<GitLabのアドレス>>/<<ユーザ名>>/<<プロジェクト名>>/raw/master
をmaven repositoriesの場所に指定することによって、GitLab上にあるライブラリを取得できるようになります。
ワーイ